Skip to content

Instantly share code, notes, and snippets.

@col000r
Created July 8, 2014 16:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save col000r/c85a21cfb144eeb9742d to your computer and use it in GitHub Desktop.
Save col000r/c85a21cfb144eeb9742d to your computer and use it in GitHub Desktop.
Make a camera look at an object, make it smoothly follow its path, and don't jerk-turn around when it moves beyond 0 or 360 degrees, dammit.
using UnityEngine;
using System.Collections;
/// <summary>
/// Put this script on a camera, assign a target and the camera will always look at that target, smoothly following it.
/// </summary>
public class CameraLookAt : MonoBehaviour {
public Transform target; //Look at this
private Transform aimTarget;
private Vector3 aimAngle = Vector3.zero; //eulerAngles from aimTarget will go in here
private Vector3 finalAngle = Vector3.zero; //this is not clamped between 0 and 360, it will go on and on...
void Start() {
//Ok. We can't do LookAt directly on this transform, because we want smooth motion.
//So, let's create a Transform that will do the LookAt, then we'll lerp towards it's eulerAngles
GameObject go = new GameObject("CameraLookAt AimTarget");
go.transform.parent = transform.parent;
go.transform.position = transform.position;
aimTarget = go.transform;
aimAngle = finalAngle = transform.eulerAngles;
}
void LateUpdate () {
aimTarget.LookAt(target, Vector3.up); //dummy looks at target
aimAngle = aimTarget.eulerAngles; //take angles from dummy
//this is where the magic happens. let's add or subtract 360f until aimAngle is within 360f of the finalAngle
while(aimAngle.y - finalAngle.y > 180f) aimAngle.y -= 360f;
while(aimAngle.y - finalAngle.y < -180f) aimAngle.y += 360f;
finalAngle = Vector3.Lerp(finalAngle, aimAngle, Time.deltaTime * 2f); //now lerp towards the aligned aimAngle.
//this might come as a surprise. after all the hassle to get around the 0-360 clamping that happens in eulerAngles, we're now clamping it back to 0-360.
while(finalAngle.y < 0f) finalAngle.y += 360f; //why? to avoid errors due to float imprecision.
while(finalAngle.y > 360f) finalAngle.y -= 360f; //uncomment these 2 lines, turn the camera around its axis 1000 times and you'll see what I mean. (it will start shaking/studdering)
transform.eulerAngles = finalAngle; //assign finalAngle, done!
}
/// <summary>
/// Assign a new target to look at
/// </summary>
/// <param name="t">the new target</param>
public void LookAtMe(Transform t) {
target = t;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment