Problem when rotating camera.

Hi.

I have a camera that follows the player that i made for a top down game and i’m trying to rotate it using Q and E.
But when i rotate the camera, it causes some issues with the player movement, like inversing it when i try to walk.
Is there a way to fix it? Here are the scripts:

Camera follow:

private void FixedUpdate()
    {
        Vector3 desiredPosition = target.position + offset;
        Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
        transform.position = smoothedPosition;

        if (Input.GetKey(KeyCode.E))
        {
            transform.Rotate(0, rotateSpeed * Time.deltaTime, 0, Space.World);
        }
        if (Input.GetKey(KeyCode.Q))
        {
            transform.Rotate(0, -rotateSpeed * Time.deltaTime, 0, Space.World);
        }
    }

And the player movement script:

void Move(float h, float v)
    {
        Vector3 movement = new Vector3(h, 0f, v);

        movement = movement.normalized * walkSpeed * Time.deltaTime;

        rb.MovePosition(transform.position + movement);
    }

A couple of things. First, it seems weird/wrong for you camera movement to be within FixedUpdate. I’d suggest moving that code to Update for smoother movement. FixedUpdate is generally just for code that manipulates a rigidbody.

I don’t see why the player’s movement would be in any way tied to the camera. From the code you posted, it doesn’t look like it should, unless the “h” and “v” you’ve passed in are somehow relative to the rotation of the camera?

I’m not passing the values relative to the camera. The problem is that every time i rotate the camera, it messes completely the movement of the player. Also, i’m rotating the player to the mouse position by raycasting its position on the screen, maybe this is what is causing the problem? If yes, is there a way to fix this?

Edit: I just tested and it’s not the rotate to mouse feature that is causing the problem, it’s the script that rotates the camera. Don’t know how to fix this…

Anyone?

If I understand this correctly, you walk with WASD and this will be mapped to h and v variables, right?

And you want to rotate the Camera with Q and E. This does not affect the player.

The problem may be:

If you rotate the camera to the right, your looking vector will change to the left. If you now move your player by pressing W (forward) he will move forward. But in world space coordinates. To the player it will seem that he is moving to the right. So if you want the player to walk in the direction the camera is looking (and therefore the player) you will have to get the rotation from the camera to the player.

It would actually be best, if the player only controls the player and not the camera. The player should identify with the player and not the camera (if that is type of game you want)

For that, rotate the player as you are in this script and attach the camera to the player, but on top of him. If you want a smoooth rotation, take the rotation (only z axis) from the player and lerp the cameras rotation to this value.

I’ve attached an example package for you.

public class CamScript : MonoBehaviour
{
    public Transform Target;
    public float SmoothSpeed = 2f;  
  
    private void Update()
    {
        transform.rotation = Quaternion.Lerp(transform.rotation, Target.rotation, Time.deltaTime * SmoothSpeed);
        transform.position = Vector3.Lerp(transform.position, Target.position, Time.deltaTime * SmoothSpeed);
    }
}
public class Player : MonoBehaviour
{
    public Rigidbody Rb;
    public float WalkSpeed = 1f;
    public float RotateSpeed = 2f;
  
    void Update()
    {
        float forward = Input.GetKey(KeyCode.W) ? 1 : Input.GetKey(KeyCode.S) ? -1f : 0f;
        float sideward = Input.GetKey(KeyCode.A) ? -1 : Input.GetKey(KeyCode.D) ? 1f : 0f;
      
        Rotate();
      
        Move(forward, sideward);
    }

    void Move(float forward, float sidewards)
    {
        Vector3 movement = transform.forward * forward + transform.right * sidewards;
      
        movement = movement.normalized * WalkSpeed * Time.deltaTime;
      
        movement.y = 0f;
      
        Rb.MovePosition(transform.position + movement);
    }

    void Rotate()
    {
        if (Input.GetKey(KeyCode.E))
        {
            transform.Rotate(0, RotateSpeed * Time.deltaTime, 0, Space.World);
        }
        if (Input.GetKey(KeyCode.Q))
        {
            transform.Rotate(0, -RotateSpeed * Time.deltaTime, 0, Space.World);
        }
    }
}

4380826–397642–PlayerMovement.unitypackage (6.43 KB)

1 Like

Thanks, this works! But i still want to rotate my player to the mouse position instead of rotating him with Q and E.
Here is the function that i’m using to do that:

void Turning()
    {
        Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);

        RaycastHit floorHit;

        if (Physics.Raycast(camRay, out floorHit, camRayLength, floorMask))
        {
            Vector3 playerToMouse = floorHit.point - transform.position;

            playerToMouse.y = 0f;

            Quaternion newRotation = Quaternion.LookRotation(playerToMouse * Time.deltaTime);
            Rb.MoveRotation(Quaternion.Lerp(Rb.rotation, newRotation, turnSpeed * Time.deltaTime));
        }
    }

How do i make it work with your movement script?

Vector3 playerToMouse = floorHit.point - transform.position;

You don’t need to subtract the player position from the hitpoint. LookRotation wants a world space point, not a local space point.

Quaternion newRotation = Quaternion.LookRotation(playerToMouse * Time.deltaTime);

I did not test your code, but I would remove the time multiplication from LookRotation as this is where the player want too look. This should not increase. The rest seems fine and should work.

You would have to replace my Rotation() method with your Turning method to make this work. The camera should not be affected by this.

1 Like

I tested it and your movement script is not working with the Turning() method unfortunately. It is inverting all the controls, even if i don’t rotate the camera…

Does anyone know how to fix this issue that happens with the player movement when i rotate the camera?

If the movement is inverted, why don’t you invert the inputs? If left should be right, then change it in the input handling.

1 Like

Ok, i’ll try it. Thanks for the tip.