Recently I have been working on a 2D platformer which uses the inbuilt Unity Physics and Rigidbodies.
One of the challenges I ran into was that when the player moved above a certain velocity, it would sometimes pass through colliders. This would lead to the player getting stuck inside the floor when landing a from a high jump.
It’s an issue faced by all physics engines, not just Unity, although severity may vary between platforms. It also extends to both 2D and 3D.
It’s for this reason many game developers try to avoid pre-built physics systems and instead look for simpler hand crafted alternatives.
Before we look at a solution, it’s a good idea to first understand why this is happening. Below I have included an exerpt from Matias Gil who did a good job explaining it.
“The problem with physics collision detection is that sometimes when the speed of an object is too high (in this case as a result of a force added to the rigid body) the collision won’t be detected. The reason is that the code you are executing is running at x amount of steps per seconds, so sometimes the rigidbody will go through the collider between one step to another. Lets say you have a ball at 100 miles per hour and a wall that is 1 feet wide, the code will move the ball a determined amount of feet every time the code is run according the physics of it, so the movement of the ball is virtualized but it’s not a real physical movement, so it can happen that from one step to another the ball can move from point a to b and the wall is between those points. As a result the collision will not be detected.”
There is no one solution for this, and each comes with i’ts own pro’s and con’s that must be weighted up in the context of your game.
Below are some of the solutions I discovered through my own trials.
These are simply concepts for you to explore, I make no guarantee they will solve your issues.
Rigidbody Collision mode
Changing your players Rigidbody collision mode to from ‘Discrete‘ to ‘Continuous‘. Continuous Collision Detection (CCD) will instantly fix the collider overlap problem, but it is much more performance intensive and can easily lead to frame rate issues, especially on mobile. It really depends on the complexity of your game, but definitely the easiest fix to implement. ** I have only tested this in 2D mode, I’ve heard talk of CCD having issues in 3D. I cannot confirm this however
Minimum Penetration is a property that resides in the physics settings tab (Edit > project settings > physics/2D > Min Penetration). It represents the collider overlap Unity will allow before flagging a collision. By default the minimum penetration is set to 0.05.
In some cases it is possible to tweak this setting to allow for slightly less collider overlap, the sweet spot will be relevant to your players mass/gravity, so it will require some trial and error.
Reducing this property too much will lead to characters vibrating.
Edge Colliders vs Box Colliders
Edge colliders can effectively be used for terrain, whether they are faster than Box Colliders is arguable, but that’s a separate topic. The problem is they are only a pixel thick, which makes them real easy to pass through if a Rigidbody is moving fast enough.
It may be a better idea for some games to use Box Colliders over Edge Colliders. Box collision will push your rigid body out of the box, stopping it from getting snagged. You will probably find that although Edge colliders are technically more performance friendly, the difference in most cases will not be noticeable.
If your game has a flat floor with no hills/curves, you may also consider wrapping it with with one big Box Collider.
Tweaking Physics Settings
In some situations a solution may come from simply tweaking your RigidBodies or world gravity settings, does your player really need to hit the floor like a sack of potatoes? The lower your players velocity when making contact with other colliders the less chance it has of penetrating them. If your game is about walking on the moon, the player will likely be real floaty, so your unlikely to run into the collisions described above. So perhaps you can find a middle ground between potato sack and moon man which fits your game.
Fail Safe Checks
Another option could be to set up kind of a security check with a raycast. You could set a raycast in a specific direction to determine if that object is about to hit something. You would then have to come up with some logic to handle if the collision has failed based on the ray casts expectations. I haven’t personally tried this approach but I have come across it discussed on Stack threads. I’d personally avoid it unless your game has some edge case situation that the previous points cant solve.
Check out this link for a similar approach using Rigidbody and raycasing together.
Hopefully you can sort it out without attempting the last, as it can lead to it’s own complexities.
Reddit Member Dr9 Has also suggested if working in 3D with terrains, to change the terrain thickness, as the default is too low if you have ‘spikey’ mountains.