0
\$\begingroup\$

I have a 3rd person camera which can rotate around the player. My problem is that wherever camera is facing, players forward is always the same direction.

For example when camera is facing the right side of the player, when I press button to move forward, I want player to turn to the left and make that the "new forward".

My camera script so far:

using UnityEngine;
using System.Collections;

public class PlayerScript : MonoBehaviour
{
    public float RotateSpeed = 150,
    MoveSpeed = 50;
    float DeltaTime;

    void Update()
    {
        DeltaTime = Time.deltaTime;
        transform.Rotate(0, Input.GetAxis("LeftX") * RotateSpeed * DeltaTime, 0);
        transform.Translate(0, 0, -Input.GetAxis("LeftY") * MoveSpeed * DeltaTime);
    }
}

public class CameraScript : MonoBehaviour
{
    public GameObject Target;
    public float RotateSpeed = 170,
    FollowDistance = 20,
    FollowHeight = 10;
    float RotateSpeedPerTime,
    DesiredRotationAngle,
    DesiredHeight,
    CurrentRotationAngle,
    CurrentHeight,
    Yaw,
    Pitch;
    Quaternion CurrentRotation;

    void LateUpdate()
    {
        RotateSpeedPerTime = RotateSpeed * Time.deltaTime;

        DesiredRotationAngle = Target.transform.eulerAngles.y;
        DesiredHeight = Target.transform.position.y + FollowHeight;
        CurrentRotationAngle = transform.eulerAngles.y;
        CurrentHeight = transform.position.y;

        CurrentRotationAngle = Mathf.LerpAngle(CurrentRotationAngle, DesiredRotationAngle, 0);
        CurrentHeight = Mathf.Lerp(CurrentHeight, DesiredHeight, 0);

        CurrentRotation = Quaternion.Euler(0, CurrentRotationAngle, 0);
        transform.position = Target.transform.position;
        transform.position -= CurrentRotation * Vector3.forward * FollowDistance;
        transform.position = new Vector3(transform.position.x, CurrentHeight, transform.position.z);

        Yaw = Input.GetAxis("Right Horizontal") * RotateSpeedPerTime;
        Pitch = Input.GetAxis("Right Vertical") * RotateSpeedPerTime;
        transform.Translate(new Vector3(Yaw, -Pitch, 0));
        transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z);

        transform.LookAt(Target.transform);
    }
}
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

(coincidentally I just wrote about this topic for my book. That chapter should be released next week; here's a brief summary)

There are two primary steps to what you're trying to do: 1) Determine which direction to face 2) Rotate the player to face that direction

The first task is handled via transforming the direction vector from camera-space to world-space. That is, take the "left" direction of the camera and transform that into a global direction, something like this in the player script:

Vector3 movement = new Vector3(Input.GetAxis("LeftX"), 0, 0);
movement = cameraTransform.TransformDirection(movement);

The second step is handled by turning the direction vector into a quaternion and then setting that as the player's rotation, something like:

transform.rotation = Quaternion.LookRotation(movement);

Although that will snap to the new direction instantly; if you want the player to smoothly rotate to the new direction then you should use Lerp:

Quaternion direction = Quaternion.LookRotation(movement);
transform.rotation = Quaternion.Lerp(transform.rotation,
                                     direction, rotSpeed * Time.deltaTime);
\$\endgroup\$
9
  • \$\begingroup\$ Could you fit that into Player Movement code as I'm not sure where should I put it? I'll edit my question. Thank you. \$\endgroup\$ Commented Aug 17, 2014 at 21:39
  • \$\begingroup\$ I'm sorry, how do I add reference? I've been trying few things around but don't know how to make it work. Also, that "to smoothly rotate to the new direction" has 3 errors. \$\endgroup\$ Commented Aug 21, 2014 at 23:28
  • \$\begingroup\$ Like this? Probably not as it is not working: public int cameraTransform = Transform; \$\endgroup\$ Commented Aug 22, 2014 at 9:36
  • \$\begingroup\$ oh...I have to say that I'm bad at c#...you probably noticed this by now. It doesn't work as I did something wrong. That camera script is attached to the camera. Also, I don't see a place to drag camera in. I put public transform cameraTransform; below float DeltaTime; \$\endgroup\$ Commented Aug 22, 2014 at 18:25
  • \$\begingroup\$ I know what inspector is...what I don't see is place inside CameraScript where I can drag in camera \$\endgroup\$ Commented Aug 22, 2014 at 18:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .