Created
August 18, 2015 18:26
-
-
Save nonathaj/119a428130cf8c506dc9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
/// <summary> | |
/// Camera Follower | |
/// | |
/// Causes a camera to follow the position of a provided transform, and optionally it's x/y/z rotatations. | |
/// The camera can zoom out, in either orthographic or perspective mode and is limited on both ends. | |
/// | |
/// Do NOT parent this component's gameobject to the follow transform. It must be at the same transform level, or higher. | |
/// </summary> | |
[RequireComponent(typeof(Camera))] | |
public class CameraFollower : MonoBehaviour | |
{ | |
private Camera cam; | |
public Camera Cam { | |
get { | |
if (cam == null) | |
cam = GetComponent<Camera>(); | |
return cam; | |
} | |
} | |
[SerializeField, Tooltip("What Transform are we following?")] | |
Transform followTransform; | |
public Transform FollowTransform { get { return followTransform; } } | |
public enum MoveType { Direct, Lerp, MoveTowards } | |
[SerializeField, Tooltip("What method of movement toward our desired position should we use?")] | |
MoveType movementType; | |
public MoveType MovementType { get { return movementType; } set { movementType = value; } } | |
[SerializeField, Tooltip("How quickly do we move toward our relative follow transform position? (Does nothing when Movement Type is set to Direct)")] | |
float MoveSpeed = 10; | |
[SerializeField, Tooltip("What method of movement toward our desired rotation should we use?")] | |
MoveType rotationType; | |
public MoveType RotationType { get { return rotationType; } set { rotationType = value; } } | |
[SerializeField, Tooltip("How quickly do we move toward our relative follow transform rotation? (Does nothhin when Rotation Type is set to Direct)")] | |
float rotationSpeed = 10f; | |
public float RotationSpeed { get { return rotationSpeed; } set { rotationSpeed = value; } } | |
[SerializeField, Tooltip("Should we follow the Follow Transform's X Rotation")] | |
bool followXRotation = false; | |
[SerializeField, Tooltip("Should we follow the Follow Transform's Y Rotation")] | |
bool followYRotation = false; | |
[SerializeField, Tooltip("Should we follow the Follow Transform's Z Rotation")] | |
bool followZRotation = false; | |
[SerializeField, Tooltip("How quickly can we zoom in and out?")] | |
float zoomSpeed = 10f; | |
public float ZoomSpeed { get { return zoomSpeed; } set { zoomSpeed = value; } } | |
[SerializeField, Tooltip("What is the min/max amount of our zoom?")] | |
Vector2 zoomRange = new Vector2(10f, 100f); | |
public Vector2 ZoomRange { get { return zoomRange; } set { zoomRange = value; } } | |
/// <summary> | |
/// Our desired position, relative to the follow transform | |
/// </summary> | |
public Vector3 RelativeToFollow { get; set; } | |
/// <summary> | |
/// Our World space desired position | |
/// </summary> | |
public Vector3 DesiredPosition { | |
get { | |
return FollowTransform.position + FollowedRotation * RelativeToFollow; | |
} | |
} | |
/// <summary> | |
/// What segment of the FollowTransform's rotation are we actually using? | |
/// </summary> | |
public Quaternion FollowedRotation { | |
get { | |
Vector3 relativeRotation = Vector3.zero; | |
if (followXRotation) | |
relativeRotation.x = FollowTransform.eulerAngles.x; | |
if (followYRotation) | |
relativeRotation.y = FollowTransform.eulerAngles.y; | |
if (followZRotation) | |
relativeRotation.z = FollowTransform.eulerAngles.z; | |
return Quaternion.Euler(relativeRotation); | |
} | |
} | |
public Quaternion DesiredRotation { | |
get { | |
Vector3 desiredRotation = transform.eulerAngles; | |
if (followXRotation) | |
desiredRotation.x = FollowTransform.eulerAngles.x; | |
if (followYRotation) | |
desiredRotation.y = FollowTransform.eulerAngles.y; | |
if (followZRotation) | |
desiredRotation.z = FollowTransform.eulerAngles.z; | |
return Quaternion.Euler(desiredRotation); | |
} | |
} | |
void Awake() | |
{ | |
RelativeToFollow = transform.position - FollowTransform.position; | |
} | |
void Update() | |
{ | |
Follow(Time.deltaTime); | |
if (Input.GetAxis("Mouse ScrollWheel") > 0) | |
ZoomIn(); | |
if (Input.GetAxis("Mouse ScrollWheel") < 0) | |
ZoomOut(); | |
} | |
public void ZoomIn() { ModifyZoom(-ZoomSpeed); } | |
public void ZoomOut() { ModifyZoom(ZoomSpeed); } | |
public void ModifyZoom(float amount) | |
{ | |
if (Cam.orthographic) | |
Cam.orthographicSize = Mathf.Clamp(Cam.orthographicSize + amount * Time.deltaTime, ZoomRange.x, ZoomRange.y); | |
else | |
Cam.fieldOfView = Mathf.Clamp(Cam.fieldOfView + amount * Time.deltaTime, ZoomRange.x, ZoomRange.y); | |
} | |
void Follow(float deltaTime) | |
{ | |
if (MovementType == MoveType.Direct) | |
transform.position = DesiredPosition; | |
else if (MovementType == MoveType.Lerp) | |
transform.position = Vector3.Lerp(transform.position, DesiredPosition, MoveSpeed * deltaTime); | |
else if (MovementType == MoveType.MoveTowards) | |
transform.position = Vector3.MoveTowards(transform.position, DesiredPosition, MoveSpeed * deltaTime); | |
if (RotationType == MoveType.Direct) | |
transform.rotation = DesiredRotation; | |
else if (RotationType == MoveType.Lerp) | |
transform.rotation = Quaternion.Lerp(transform.rotation, DesiredRotation, RotationSpeed * deltaTime); | |
else if (RotationType == MoveType.MoveTowards) | |
transform.rotation = Quaternion.RotateTowards(transform.rotation, DesiredRotation, RotationSpeed * deltaTime); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment