Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have implemented a follow camera in Unity 3D. However, if the player object rotates, the camera does not rotate with it. To fix this I used RotateAround as follows:

playerRotation = CastPositive(player.EulerAngles.y) //guarantees 0-360
cameraRotation = CastPositive(transform.EulerAngles.y)
difference = playerRotation - cameraRotation
transform.RotateAround(player.position, Vector3.up, difference * time.deltaTime)

This works in general. However at some point the difference snaps from -50 to 210. When this happens, the camera swings in the opposite direction all the way round the player object, instead of continuing on its orbit.

How can I avoid this value jump?

  • I've tried clamping the various values to no avail, but maybe I've missed something?
  • Quaternions?
share|improve this question

2 Answers 2

I don't know which is the specific error in your case, but at least from my experience, I'd use quaternion instead. You can just lerp between your current camera rotation and the desired one. Something like:

transform.rotation = Quaternion.Lerp(transform.rotation, player.transform.rotation,Time.deltaTime * speed);

In general quaternions offer a simple and natural way to interpolate rotations, preventing problems like gimbal lock.

share|improve this answer
up vote 0 down vote accepted

Code provided by Katherine Rix:

// Position camera to follow behind player's head.
private void Follow(){

    // orientation as an angle when projected onto the XZ plane
    // this functionality is modularise into a separate method because
    // I use it elsewhere
    float playerAngle = AngleOnXZPlane (player);
    float cameraAngle = AngleOnXZPlane (transform);

    // difference in orientations
    float rotationDiff = Mathf.DeltaAngle(cameraAngle, playerAngle);

    // rotate around target by time-sensitive difference between these angles
    transform.RotateAround(GetTarget(), Vector3.up, rotationDiff * Time.deltaTime);
}

// Find the angle made when projecting the rotation onto the xz plane.
// You could pass in the rotation as a parameter instead of the transform.
private float AngleOnXZPlane(Transform item){

    // get rotation as vector (relative to parent)
    Vector3 direction = item.rotation * item.parent.forward;

    // return angle in degrees when projected onto xz plane
    return Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.