How to achieve a smooth landing (after jumping) with a First Person Ridibody controller?

Hello,

I am currently working on a first person controller for a prototype of a game I want to create. I have made multiple first person controllers in the past, but I am trying to make this one as polished as possible. I am using Unity editor 6.1 for a 3D URP project.

I have created my character controller to be Rigidbody based, and I will share the code below. The Update, FixedUpdate, and Start are controlled by a parent script attached to the same game object as the controller.

I tried fixing the problem various ways, and tried to find my problem online but alas I couldn’t find a solution. I even tried attaching a zero friction physics material to the player’s collider, but that did not fix it either.

Also attached is a video of my problem, but I will explain it here. My problem is that when landing from falling or from a jump, the player’s Rigidbody will freeze for a couple frames before continuing. The X and Z velocity of the Rigidbody do not change before or after landing, only the Y velocity due to the collision. I am not sure if this is unavoidable due to the Unity physics system, but I figured it wouldn’t hurt to ask. And yes, I know I could likely hide the stutter with camera movement or an animation of some kind, but I would like the movement to feel very polished as I aim for this to be somewhat of a movement shooter.

It is kind of hard to tell from the video, but I could also very well just be a perfectionist, let me know if this is something I should overlook.
Thank you to anyone who takes the time to help me, I appreciate it.

Code.txt (6.7 KB)

Create the prototype, not a character controller!

Just like you don’t write an HTML renderer before designing a website. Character controllers are a solved problem, just like scripting the camera is thanks to Cinemachine.

Since you’re a perfectionist, you will either get frustrated and stop, or you’ll spend weeks and months just on the controller itself to achieve functionality that you can get elsewhere for free.

Which is rarely a good idea because the player’s input has no authority over the physics simulation. So you’ll be fighting physics a lot. It’s best to make a kinematic character controller, it offloads collision detection and response onto you but for everything else you have full control.

My hunch is that your collision detection / flight handling code is buggy. I suppose your “maintain momentum” code kicks in when it shouldn’t.

From the looks of it, as the player is falling towards the ground it is naturally accelerating due to velocity. But something keeps stopping the velocity increment, using fixed Y velocity every frame. This might either be the “keep momentum” thing or a simple bug where it’s only due to order of operations that the player still floats down at a fixed rate.

One possible case that makes it look like slowly floating towards the ground:

  • something clears the Y velocity (set to 0)
  • add Y velocity to accelerate falling
  • update player’s velocity

Thus only the “gravity acceleration per frame” value gets applied every frame. The fix would be to first apply downward gravity and only just before applying velocity to the player should any checks occur that might hard reset the velocity.

This ^ ^ … surprised CodeSmile didn’t throw in the kinematic ctrlr link! I will…

Here is a free Kinematic Character Controller that also comes with a huge playground:

When creating a physics material with no friction it’s important to set the ‘Friction Combine’ to Minimum. Another option is using the ‘Continuous Speculative’ collision detection mode to help prevent your character from sinking into the ground upon landing.

This worked! I changed to Continuous Speculative and the issue stopped. Thank you all very much for responding, I will take your advice to heart.