Third Person Camera: Problem with Player rotation

Hey there,

I’m actually quite sure this was asked before, but I wasn’t able to find a solution that fits my needs.

Basically, I need some help with writing a script that makes my player look towards the direction he’s walking to. (Like in Dark Souls, Uncharted or most other 3rd Person Games)
I’m using Input.GetAxis for getting the input from my Keyboard and my Controller. Additionally, I’ve got a Camera i can move around the player. Therefore, i need to consider the current camera rotation before I apply movement to my player, because pushing forward should move my player different if my camera is looking at my player at a different angle.

Right now I’ve got this:

    private void SetLookRotation()
    {
        Vector3 eulerLook = WorldCamera.Instance.transform.eulerAngles;
        eulerLook.x = 0;
        eulerLook.z = 0;
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(eulerLook), Time.deltaTime * 4);
    }

    private void ApplyMovement()
    {
        movementVector = transform.forward * Input.GetAxis("Vertical") + transform.right * Input.GetAxis("Horizontal");
        transform.position += movementVector * movementSpeed * Time.deltaTime;
    }

This way, my player is always facing away from the camera, but not towards other directions.
I hope its clear what i need help with.
Cheers

A little confused here. If you press Forward is the direction ‘Forward’ relative to the WORLD, LOCAL or the Camera?

It’s relative to the Camera.

In that case try this.

Some variables like ‘player’ and ‘camera’ assumes you have a reference to them.

Horizontal is a float that is movement along the X Axis
Vertical is a float that is movement along the Y Axis

Rotation

Vector3 direction = new Vector3(horizontal, 0.0F, vertical);
Quaternion rotation = player.rotation;

if(direction.magnitude > 0.01F) {
    direction = camera.transform.TransformDirection(direction);
    direction.y = 0.0F; // we don't care.
    rotation = Quaternion.LookRotation(direction, Vector3.up);
}

So TransformDirection takes local facing Vector and transforms it into a World Vector relative to its Forward Vector. So since you want to move forward relative to the camera thats how you do it. Use the rotation variable to rotate your player. For movement, this is easy too.

Movement Assumes Rigidbody

Vector3 forward_vector = camera.transform.forward * vertical * runSpeed;
Vector3 strafe_vector = camera.transform.right * horizontal * runSpeed;
Vector3 velocity = forward_vector + strafeVector;
veclocity.y = player.rigidbody.y // Let gravity do this.

Hope this helps.

1 Like

Thank you, this is working beautiful :slight_smile:

In the meantime I managed to somewhat solve this problem as well, but your approach is much nicer.

What i did was creating a new empty GameObject, set it to 0,0,0 and made it a child of my Camera. After that, I added my direction Vector (horizontal, 0, vertical) to the empty GameObject’s position and reset it upon releasing my keys. Then, i could use transform.LookAt(thatGameObject) to make my player look at that gameObject.
Well, this was working. What bugged me was, I wasn’t able to smooth the rotation while using LookAt(). At least not with some extra code.

So, thanks again for your help :slight_smile: I use your approach now :wink:

Cheers.

EDIT:
For others who are seeing this:
Don’t forget to add “transform.rotation = rotation” after calculating the rotation :wink:

Awesome glad to help!

If you want some extra smoothing you can use Quaternion.Lerp or Slerp