Slower movement when looking down/up

I think I made this type of thread before, but I don’t remember, and I don’t see anything on my threads list. If I did, I probably didn’t get it solved.

Anyway, I’m trying to make my character’s movement relative to the camera, which I almost fully accomplished. The turning works, and so does the movement on x and z axis. The problem is the y.

Before, the character was turning down when I looked down, and on his back when I looked up. I stopped this by setting the Vector3’s y to 0.

movement.y = 0;

That stops the y rotation in relation to the camera, but not the movement. The movement still tries to move the player’s y position in relation to the camera.

I’ve looked, but I only found an Answers post which had no replies, and a thread which has an a working solution. The problem is, it doesn’t work for me. I copied the code that apparently solved the problem for the OP, but it doesn’t do anything for me. I assumed that in theory it should also work for me, but it seems to be a specific solution to the code the OP had.

Here is code I currently have:

    //Movement variables
    public float moveSpeed;
    float translation;
    float strafe;

    //Rotation variables
    public float rotationSpeed;

    public Transform t_Reference;
    public Transform t_Camera;

    void FixedUpdate () {
        //Movement
        strafe =  Input.GetAxis ("Horizontal") * Time.fixedDeltaTime;
        translation = Input.GetAxis ("Vertical") * Time.fixedDeltaTime;

        Vector3 movement = new Vector3 (strafe, 0, translation);
        movement = Camera.main.transform.TransformDirection(movement);
        movement.y = 0;
        transform.Translate (movement * moveSpeed, Space.World);

        //Rotation
        if (movement != Vector3.zero) {
            transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation (movement), rotationSpeed);
        }
    }

    void Update () {
        t_Reference.eulerAngles = new Vector3(0, t_Camera.eulerAngles.y, 0);
    }

Any ideas how to keep the y position relevant to world space rather than the camera’s looking direction?

I had this problem in my current game, and solved it by normalizing the Camera’s transform…
You might be able to do it simply this way, with how your script is:

movement = Camera.main.transform.TransformDirection(movement);
movement.y = 0;
movement.Normalize();

Give that a whirl.

You might have to tackle it a slightly different way though since you’re already applying your input values before that (and therefore those would be normalized too, which probably isn’t desirable), but hopefully this gives you enough to figure it out on your own.

My script was like so:

moveDirection = Vector3.zero;
moveDirection += camUpNormalized * inputMoveVertical;
moveDirection += camRightNormalized * inputMoveHorizontal;

There’s a fair bit more to it than that, but that’s essentially the piece you’re stuck on.

And this was probably an overly verbose way of doing it, but here’s the code behind cam*Normalized:

        camUpNormalized = mainCamera.transform.up;
        camUpNormalized.y = 0.0f;
        camUpNormalized.Normalize();

        camRightNormalized = mainCamera.transform.right;
        camRightNormalized.y = 0.0f;
        camRightNormalized.Normalize();
2 Likes

I still can’t figure it out. :frowning:

Movement and controlling a character has always been my weak point in coding. I’m not surprised this is taking me so long to solve.

Thanks for the info though. It does clear up some stuff. And yes, normalizing the movement in this case is not desirable. Although it does solve the issue, it causes the character to go super fast, and the stopping and starting to feel really stiff.

I tried a lot of stuff since your reply, and nothing worked. Your suggestion is the closest thing to a solution so far.

After normalizing, you get the direction you want to move to. You still need to multiply it by the speed in which you want to move in that direction. Then multiply again by Time.deltaTime to get the movement amount for the current frame.

In short:

float walkingSpeed = 1.4f;  // meters per second
Vector3 movement = whatever...;
movement.y = 0;
movement = movement.normalized * walkingSpeed * Time.deltaTime;
2 Likes

Did you try the other way I had suggested like how I have it in my script?

The gist of it is, I normalized my camera values on their own… then multiply the normalized camera values by the inputs to get the movement vector. The only thing is, you need to ensure that each time your camera angle changes, you recalculate/normalize your camera values. There were some challenges for me with all of that too, but managed to get through them all.

But just be sure however you do things, don’t normalize your input values (as that wouldn’t allow your user to slowly move the player with lesser analog movements - which it sounds like you want). And as Pete just added, ensure you’re still modifying the movement vector by your movement speed and deltaTime like before… and actually it looks like you weren’t multiplying by deltaTime before, but you should be, to ensure consistent movement at diff FPS.

1 Like

FYI, the way I found I needed to normalize my camera transform values was just by looking at them as I played the game. You can see that when you angle the camera at a view that isn’t exactly pointing down one of the axes, it will cause two of the axis to have values that vary from 0 and 1 quite a bit. I am not sure how to really explain that, it’s best just to see for yourself, so I normalized those values and that ended up fixing things how I’d expect.

The only other issue I had from there was diagonal movement, which I also have a fix for, if you run into that.

One way to wrap your head around the camera thing is to look at the camera in the scene view and see where your forward axis points for your camera, and you’ll see it is of course angled upward a bit. I should almost draw this out, maybe… imagine a vector going in the direction of that camera’s forward transform… imagine it 1 unit in length… now go straight down from the end of that vector to 0 on the Y… and then go back to the origin of that vector on the 0 on the Y, and you’ll get a vector that is less than 1 in length… that’s why the movement is all out of wack if you don’t normalize. hope that made sense!

1 Like

That worked, thanks. :slight_smile:

Although there is a weird thing happening. When I look down while moving diagonally, the character rotates a bit. And also, the diagonal movement isn’t a 45 degree one, but rather a 10-20 one, which is also unexpected.

Yes, but it made the character move strangely in relation to the camera, and I didn’t want to dig deeper and dig up even more issues to solve.

Actually it’s not. The movement is meant for keyboard only for now. Thanks for the tip though.

Ahh OK, that definitely is easier to work with :slight_smile:

Glad it works for you now!

1 Like