Player moves up and down when Camera looks up and down

Hey, I’ve been following this tutorial by Mikes Code (https://www.youtube.com/watch?v=swOfmyJvb98&list=PLtLToKUhgzwm1rZnTeWSRAyx9tl8VbGUE&index=1&t=1s) on how to create an FPS game, and I’ve gotten about halfway through all of the tutorials. Just now though I realized that when my character looks down or up and then presses a movement key, the player moves that direction. For example, my character looks up into the sky and presses W, the player then moves into the sky as if it had been jumping. I’m not sure how to resolve. Attached below is the area of code I believe the issue lies in.

this.void Update()
    {
        // Grounded is true or not. Basically ground check
        isGrounded = Physics.Raycast(groundCheck.position, Vector3.down, groundDistance, groundMask);
        Debug.DrawLine(groundCheck.position, groundCheck.position + Vector3.down * groundDistance, Color.red);
        // reseting the defauly velocity
        if (isGrounded && velocity.y < 0)
        {
            velocity.y = -2f;
        }

        // Getting the inputs
        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        // creating the moving vector
        Vector3 move = Camera.transform.right * x + Camera.transform.forward * z; //(right - red axis, forward - blue axis)

        // Actually moving the character
        controller.Move(move * speed * Time.deltaTime);


You’re taking the camera’s forward angle to move, and since the camera is angled upwards when looking up, then the player is moving in the same angled direction. You need to correct the vector so that it is not rotated vertically and is instead parallel to the ground. You can do this by setting its y value to 0 (and preferably normalizing it so that it always has the same magnitude).

Ideally you’d have a player character that only rotates horizontally but never rotates vertically with the camera, and then you can just take that character’s forward vector for movement.

When you add gravity then it should be enough to keep your character on the ground. Alternatively it may be enough to just replace line 17 with:

Vector3 move = Camera.transform.right * x + transform.forward * z;

If the above suggestions don’t help then drgrandayy’s suggestion should work.

Where would I correct this vector? I’ve tried to set the y value to zero but C# is giving me errors when I do. Sorry if its a dumb question I’m still very new to unity and C#

sadly it did not work, thank you though

Replace line 17 with:

Vector3 cameraForward = Camera.transform.forward;
cameraForward.y = 0;
cameraForward.Normalize();
Vector3 move = Camera.transform.right * x + cameraForward * z;

THANK YOU SMMMM!!! it worked perfectly I was meddling with that for so long. If you dont mind explaining what does the normalize function do?

1 Like

Glad I could help!

So when it comes to vectors, you can think of a vector as a line in 3D space, starting at co-ordinates 0, 0, 0 and ending at custom co-ordinates x, y, z.

Let’s say our vector has x, y, z values of 1, 1, 1. This would create a line that has a length of around 1.7 (sqrt of 3). Now if we had to change the y value from 1 to 0, the line in 3D space would become flat and it would end up having a shorter length - around 1.4 (sqrt of 2).

This is a problem in our case, because when we use the transform forward vector to move, the length (or magnitude) of this vector affects the speed we move at. So if we just set its y value to 0 and do nothing else, we will end up moving at a slower speed - the higher up you look, the slower the forward speed will become.

What normalizing does is, it takes the vector, keeps the direction of it the same but changes its length so that it is exactly 1 unit long. If we normalize a vector of 1, 1, 0, it is changed into ~0.7, ~0.7, 0. The direction stays the same but the values are made smaller so that the magnitude becomes 1. So basically when we normalize vectors we’re just making sure that the magnitude, and therefore the speed in this case, always stays consistent no matter the direction we’re using.

That makes a lot of sense thank you again!