Function OnCollisionEnter is not working properly in C#
Hello, squirrelfriends! Today I'll be writing about one of the things I've done in Unity: specifically, coding my own collision detection using certain aspects of Unity's physics, and simple maths & physics (for Recess Race!).
Why not just use Unity's physics?
Good question! The short answer is Unity's physics are meant for 3D movement, and they're great for that. Function OnCollisionEnter is not working properly in C# because their basic character controller uses a capsule collider. It's pretty essential for 3D, but it doesn't work for classic SNES era 16-bit platformer tropes.Consider this image:
Wile E. Coyote wishes he could do this
Now, that's not realistic. You can't stand like that! but it makes sense when you think about the strictly-rectangular collision detection they had at the time. It was a hardware/software restriction but they ran with it and made the restriction into an asset. Here's the same image with an approximation of his hit box:
He benefits from intangible toes, forehead, and right fist
The tiny part of the box touching the collision tiles supports him. Walk any further and you fall off. This feels very fair for the player: he's allowed to put his centre of gravity over a pit, but he can't support himself with just his toes. A little 'cheating' is enough. It also allows for what feels like really close calls - if an enemy swoops down and skims your helmet, but you don't get hurt, it creates a "WOW that was close" moment, which is fantastic.
Consider the same scene with a capsule collider now:
Paint capsules!
The only point that will touch the floor on a capsule is the bottom point. Since it's not touching anything, you'll fall. Then the curve of the capsule hits the corner of the tile, and you slide away from the wall and you fall. It's a different effect, and not one I'm going for in Recess Race,
Build it from the ground up (using Unity's construction materials and power tools)
So it's clear we can't use the packaged Unity character controller. It is impossible to separate from the capsule collider. So we'll have to build our own, using a box collider!
Aside: Unity Colliders, Events, and Rigidbodies
When you make a new script in Unity, it gives you the Start() and Update() functions built in. These are events that are called when Unity feels like it. Among these are the OnCollisionEnter() and OnTriggerEnter() functions. Their utility is paramount, but there are some issues. Both of them require having a Rigidbody class on one of your objects. It makes sense, because if it didn't discriminate it would be checking every collider against every collider every frame and that would take aeons.
Solution: put a Rigidbody (Component > Physics > Rigidbody) on your controller, uncheck 'Use gravity', open the Constraints class and check all of the boxes. This way we can have it use the Collision events and also control its movements at all times.
This is what your Rigidbody component should look like
Intro to Raycasts
If you're familiar as heck with Raycasts, a "Ray-man" if you will, you can skip this section.
Setup
The Raycast is a versatile tool in Unity, and it's surprisingly cheap. You can probably do hundreds of raycasts per frame and it won't do much to slow down your processing speed (but, the fewer the better).




Comments
Post a Comment