Normilize Problem with GetAxis :/

Hello i have a problem with how to normalize i want my player to have smooth movement so i use GetAxis but when i try to normalize it the player will continue moving for a short period and then stop witch is not desirable :slight_smile:

 void FixedUpdate()
    {
        myRigidBody.useGravity = false;
        if (useGravity) myRigidBody.AddForce(Physics.gravity * (myRigidBody.mass * myRigidBody.mass));
        change = Vector3.zero ;
        change.x = Input.GetAxis("Horizontal");
        change.z = Input.GetAxis("Vertical");
      
        if (change != Vector3.zero)
        {
            MoveCharacter();
        }
        //Debug.Log(change);
    }
    void MoveCharacter()
    {
      
        myRigidBody.MovePosition(transform.position + [B]change.normalized *[/B] speed * Time.deltaTime);
    }

That is what normalize does. It takes the vector and makes its length equal to 1 as long as it is nonzero.

GetAxis applies filtering to smoothly stop you, and your normalize call drives it right back to full deflection, until it reaches zero. If you use GetAxisRaw() it might work better.

HOWEVER… if you have a joystick that has even the tiniest bit of drift (0.0001 even), then you will never be able to not move: the normalize call with set it to 1 and you’ll be moving at full speed from a drifty joystick.

I recommend after line 7 above you test if the .magnitude of the input (before normalization) is below a certain amount (say 0.1f) and then set it to Vector3.zero to avoid drift.

2 Likes

If you want smooth movement, another approach is to maintain your own notion of how much movement is happening, and then when you read the input, move that notion of movement towards the input, using for example something like Vector3.MoveTowards();

This lets you explicitly control how fast the inputs can change.

Then of course when it is time to move, you would use the persistent notion of current motion, NOT the direct input, which you would only use to adjust the current motion.

Don’t use normalized but use ClampMagnitude instead. The issue with normalized is that the length of your vector will always be 1 unless the input is exactly zero. ClampMagnitude will just limit the length of the vector:

change.x = Input.GetAxis("Horizontal");
change.z = Input.GetAxis("Vertical");
change = Vector3.ClampMagnitude(change, 1f);

Of course inside your MoveCharacter method you would remove the “.normalized” part:

myRigidBody.MovePosition(transform.position + change * speed * Time.deltaTime);

Now your change vector will properly respect your sensitivity / gravity settings of your axes.

2 Likes

Ty that worked :slight_smile: