Problem with adjusting vector.

I’ve been fighting to get my controller to behave as expected.

What I want is to have two different speeds for sideways movement (X axis) and forward and backwards movement (Z Axis).

        // Get keyboard inputs
        float moveZ = Input.GetAxis("Vertical");
        float moveX = Input.GetAxis("Horizontal");

        //Handle Movement
        Vector3 horizontalMovement = transform.right * moveX; // Set new vector based on the local coordinates
        Vector3 verticalMovement = transform.forward * moveZ;
        Vector3 movement = horizontalMovement + verticalMovement; 
        movement = movement.normalized; // Normalize final vector

        // Apply speed to normalized vector
        movement.x *= _horizontalMoveSpeed * Time.deltaTime;
        movement.z *= _verticalMoveSpeed * Time.deltaTime;

        // If the player is moving then rotate his body to face the same direction as the camera.
        if (movement.magnitude > 0)
        {
            Vector3 playerRotation = new Vector3(0, _cameraFollow.transform.eulerAngles.y, 0);
            transform.rotation = Quaternion.Euler(playerRotation);
        }

        _characterController.Move(movement);

The issue I’m having seems to originate with these 2 lines.

 // Apply speed to normalized vector
         movement.x *= _horizontalMoveSpeed * Time.deltaTime;
         movement.z *= _verticalMoveSpeed * Time.deltaTime;

My character moves fine along the forward axis at the speed of verticalMoveSpeed. When i strafe left and right he moves slower at the horizontalMoveSpeed.
The issue arises when I then rotate my camera 90, so now my “forward” is facing along the x axis (if you get what i mean). Now If i try to run my forward speed seems to be the horizontalMoveSpeed. If I now strafe I seem to be running with the verticalMoveSpeed.

I have no idea whats going on.

If I remove those lines 2 lines and just do _characterController.Move(movement * speed * Time.deltaTime); Then he moves fast in both axis (which isnt what i want)

Hi @spylefkaditis

Your issue occurs because you’re modifying the X and Z components of a world oriented Vector, but you’re looking to modify your character’s local horizontal vector.


Try instead to do your modifications to horizontalMovement and verticalMovement before normalizing the vector. This will mean that the normalized vector still comes out with a magnitude of 1, so you’ll need to apply speed to it. Its direction however will be aligned based on the moveSpeed values, and you’ll end up with what you’re looking for.

//Handle Movement
         Vector3 horizontalMovement = transform.right * moveX * _horizontalMoveSpeed; // Set new vector based on the local coordinates
         Vector3 verticalMovement = transform.forward * moveZ * _verticalMoveSpeed;
         Vector3 movement = horizontalMovement + verticalMovement; 
         movement = movement.normalized; // Normalize final vector

Hope this helps!

Thanks for the reply @darksider2000 . Hmmmm I don’t think I understand your solution. It was my understanding when I normalise a vector I’m getting rid of its magnitude and just remain with the direction only. Which is why I then multiply it’s x and y components by my 2 different speeds.

If I apply your suggested code as above, then the multiplier values _horizontalMoveSpeed and _verticalMoveSpeed are ignored after normalizing the vector. If I apply a speed to it then it works, but that doesn’t actually give me the result I want of having 2 different speeds.

Sorry if I’m misunderstanding.

What I “think” is happening is that

        movement.x = movement.x * _horizontalMoveSpeed * Time.deltaTime;
        movement.z = movement.z * _verticalMoveSpeed * Time.deltaTime;

is saying “Modify the movement in regards to the world axis”. So whenever I move in global Z it’s one speed and global X another speed. That’s why when my character rotates it doesn’t change. But I don’t understand why. I thought

        Vector3 horizontalMovement = transform.right * moveX;
        Vector3 verticalMovement = transform.forward * moveZ;
        Vector3 movement = horizontalMovement + verticalMovement;

would create movement vector based on the object local coordinates so then calling _characterController.Move(movement) would move it based on those local coordinates.

Clearly i dont understand vectors