A simple solution for constant rigidbody movement without changing and clamping velocity directly

Hello, I’m studying Unity game development about 5 years, but I had about 2-3 atempt for all these time of writing player controller and they were very simple, so yesterday i started to write own player movement system. From just a beginning I ran into a problem what to use to achieve the result I want. In Unity there are two most popular ways to write player controller: CharacterController and Rigidbody. I realised that the first don’t fit to me because CC does not interact with other rigidbodies by default and is not very “physically realistic”. So I choosed the rigidbody. Those people, who worked with RB( rigidbody ) may know about very cool method as AddForce and similar. But the main reason because of whith this method doesn’t fit for movement( in some cases ) is that it will always accelerate a rigidbody, no “constant” movement speed, so someone can think that we need to limit the speed and will write something like this:

void FixedUpdate()
    {
            var targetVelocity = someMoveDirection.normalized * speed;
            Vector3 velocity = rig.velocity;
            Vector3 velocityChange = (targetVelocity - velocity);
            velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
            velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
            velocityChange.y = 0;
            rig.AddForce(velocityChange, ForceMode.VelocityChange);
    }

But such a code will always limit your rigidbody’s velocity to maxVelocityChange variable which is completely wrong way! Try to throw an massive rigididbody with enough speed into player and you will understand what I’m talking about. The result will be, for example, that player with mass 1 and speed 0 will stop some RB with mass 1000 and speed 500…

So I decided to return to AddForce method and look again what is wrong and how it can be resolved. I wanted to limit only the speed of my horizontal movement but not the velocity of RB in total. And one brilliant but at the same time simple thought came to my mind. How about adding as much force as it needed to keep the magnitude of RB’s velocity “constant”? But how to reach that? The solution is very simple!

var targetVelocity = someMoveDirection.normalized * speed;
Vector3 horizontalVelocity = rig.velocity;
horizontalVelocity.y = 0.0f;
myRB.AddForce(targetVelocity * (1 - (horizontalVelocity.magnitude / maxMovementSpeed)));

As the result I just not add force to my RB if the speed is max. I hope it will help many people! :smiley:

P.S.
I am always open to any critique. if I wrote something wrong, you always can write bellow what is incorrect.

Also if you don’t wanna go through the trouble you can use
rigidbody.velocity = transform.TransformDirection(Vector3.(left, right, back or forward) * speed).

@Bunny83 Yes, sorry, I just forgot to write clamp the value. And yes, this post is not a question, it is something like discussion for reaching simple movement :slight_smile: