I've recently been attempting (and failing) to create my own character controller for my 3D Unity game for around a week. I hate the Unity rigidbody physics system for making a character controller, as it is severely limiting in the things I can do with it.
I want to implement the move_and_slide
function that is present in Godot. This algorithm is based on these papers:
- "Improved Collision detection and Response" by Kasper Fauerby
- "Improving the Numerical Robustness of Sphere Swept Collision Detection" by Jeff Linahan
I have found one person's implementation of the algorithm for collision detection, but the problem is, they don't give any specifics on how they implemented it for themselves.
My question is: how can I implement this in Unity?
-
\$\begingroup\$ Related gamedev.stackexchange.com/questions/189714/… \$\endgroup\$Zibelas– Zibelas2025年06月04日 16:44:48 +00:00Commented Jun 4 at 16:44
2 Answers 2
If your character can be well-represented by a capsule (or sphere), then you can get this behaviour out of the box using the CharacterController component. This is designed for implementing player characters that can interface with the physics system without using a Rigidbody.
Character Controller component inspector in Unity
You can call Move() with the total displacement you want in world space, and it will try to follow that vector until it gets as close as it can to the end, collide-and-sliding along any obstacles it encounters along the way.
In these examples, the base of the character controller (blue capsule) started at the position of the white circle. Then, I issued a Move()
to tell it to collide-and-slide toward the red circle. The controller scanned along the yellow line and found its path obstructed at the location of the yellow circle. Instead of stopping, it continued to slide along obstacles until it had either used up its full movement distance (left example) or reached the point directly above the destination (right example) - whichever comes first. Note that in the right example, it collides-and-slides twice in one call: once when hitting the floor, and again when transitioning from the floor to the ramp. (My code only draws a circle at the first collision point)
This all happens in a single frame, so the player doesn't see intermediate steps in that movement. Usually, we'd be issuing much smaller moves each frame - I've exaggerated the distance here to make the behaviour easier to see.
For comparison, a Kinematic Rigidbody using MovePosition()
will not stop or slide along collisions this way: it will go directly where you tell it, even if that penetrates into or tunnels through other colliders:
If you'd really rather implement this behaviour manually, I have a Unity/C# implementation of a collide-and-slide algorithm in this answer:
That version is clamped to the XZ plane, but you can remove the line
offset.y = 0f
to remove that constraint.You can replace the calls to
SphereCast
withCapsuleCast
,BoxCast
, or multiple sweeps of different shapes, if your character isn't sphere-ish.
-
\$\begingroup\$ Thanks for the response DMGregory :D However, you may want to put your bottom answer at the top because I feel it more accurately answers the intial question I was asking. \$\endgroup\$Callumari– Callumari2025年06月09日 20:28:30 +00:00Commented Jun 9 at 20:28
-
\$\begingroup\$ Then you're in luck: Zibelas already linked to that answer in a comment, above this answer entirely. 😉 \$\endgroup\$2025年06月09日 22:11:21 +00:00Commented Jun 9 at 22:11
I hate the Unity rigidbody physics system
I really recommend you to get used to it, because without rigidbodies, you don't get collision detection either. If you want to do as much as possible yourself, then I recommend to use kinematic rigidbodies. They act as solid bodies in the physics simulation and are blocked by static colliders (e.g. the level geometry), but their own movement is not affected by collisions with other dynamic rigidbodies. This is usually the behavior you want for a player in most game genres, but it can also be useful for other kinds of game objects where you want to have full control over their movement.
In order to implement "move_and_slide" behavior, you probably want to use the Rigidbody.MovePosition method. I don't know if it uses that exact algorithm, but the behavior should be relatively similar.
But there are several other ways to move a player-character in Unity which might be more or less appropriate depending on what you actually want to make. A while ago I made a little test application demonstrating some of those ways in an interactive manner: https://philipptheprogrammer.itch.io/unity-tutorial-how-to-move-your-player.
-
\$\begingroup\$ Hmm.. I was just testing this in Unity 6 to capture some screenshots for my new answer, and I found that when a body is set to Kinematic, MovePosition() does not respect collisions at all - it moves the body to exactly the point given as input, even if that wedges it into a collision or takes it through another object. I've repeated this with static and dynamic obstacles, and with all collision detection modes. It's strange, because I could have sworn from past experience MovePosition would at least try to stop at the first collision. Maybe I was remembering behaviour from Rigidbody2D? \$\endgroup\$2025年06月07日 00:30:34 +00:00Commented Jun 7 at 0:30
You must log in to answer this question.
Explore related questions
See similar questions with these tags.