-
-
Save Zal0/b84ca842c730d29b81f0343d547e4405 to your computer and use it in GitHub Desktop.
CameraManager - 6
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
/* | |
* Camera interpolator by Zalo (http://zalods.blogspot.com) | |
*/ | |
using UnityEngine; | |
using System.Collections; | |
[RequireComponent(typeof(Camera))] | |
public class CameraManager : MonoBehaviour { | |
class CameraParams { | |
public Quaternion rotation; | |
public Vector3 offset; | |
public float fov; | |
public float near; | |
public float far; | |
public void Set(Quaternion finalRot, Camera _cam, Transform _target) { | |
rotation = Quaternion.Inverse(finalRot) * _cam.transform.rotation; //rotation relative to final_rot | |
offset = -_cam.transform.worldToLocalMatrix.MultiplyPoint(_target.position); //translation from target to current camera position (in camera local) | |
fov = _cam.fieldOfView; | |
near = _cam.nearClipPlane; | |
far = _cam.farClipPlane; | |
if(_cam.orthographic) { | |
fov = 0.1f; | |
float zOffset = -(_cam.orthographicSize) / Mathf.Tan(fov * 0.5f * Mathf.Deg2Rad) - offset.z; | |
offset.z += zOffset; | |
near -= zOffset; | |
far -= zOffset; | |
} | |
} | |
} | |
public AnimationCurve interpolationCurve = AnimationCurve.EaseInOut(0, 0, 1, 1); | |
private CameraParams fromParams = new CameraParams(); | |
private CameraParams toParams = new CameraParams(); | |
private Camera toCamera; | |
private float interpolationTime; | |
private float interpolationTimeAccum; | |
private Transform target; | |
private Camera cachedCamera; | |
void Awake() { | |
cachedCamera = GetComponent< Camera >(); | |
} | |
public static void EnableComponents(Camera _cam, bool _value) { | |
_cam.enabled = _value; | |
AudioListener toCameraAudioListener = _cam.GetComponent< AudioListener >(); | |
if(toCameraAudioListener != null) { | |
toCameraAudioListener.enabled = _value; | |
} | |
} | |
public void InterpolateTo(Camera _toCamera, Transform _target, float _time) { | |
if(_target == null) { | |
_target = _toCamera.transform; | |
} | |
//Update From Camera values | |
if (toCamera != null) { //Check if the previous target camera is still there to interpolate from it | |
EnableComponents(toCamera, false); | |
if(interpolationTimeAccum >= interpolationTime) { | |
//we don't need to care about this is the interpolation is not finished since this camera if currently being updated | |
toParams.Set(toCamera.transform.rotation, toCamera, target); | |
transform.rotation = toCamera.transform.rotation; | |
transform.position = target.position; | |
transform.Translate(toParams.offset); | |
cachedCamera.fieldOfView = toParams.fov; | |
cachedCamera.nearClipPlane = toParams.near; | |
cachedCamera.farClipPlane = toParams.far; | |
} | |
} else { | |
//Set interpolation time to 0 if there isn't any Camera to interpolate from | |
_time = 0.0f; | |
} | |
target = _target; | |
fromParams.Set(_toCamera.transform.rotation, cachedCamera, target); | |
//Update To Camera values | |
toCamera = _toCamera; | |
EnableComponents(toCamera, false); | |
//Activate interpolator | |
gameObject.SetActive(true); | |
//Restet time | |
interpolationTime = _time; | |
interpolationTimeAccum = 0.0f; | |
} | |
void Refresh() { | |
float t = interpolationCurve.Evaluate(interpolationTimeAccum / interpolationTime); | |
toParams.Set(toCamera.transform.rotation, toCamera, target); | |
cachedCamera.fieldOfView = Mathf.Lerp(fromParams.fov, toParams.fov, t); | |
//Rotate | |
transform.rotation = toCamera.transform.rotation * Quaternion.Lerp(fromParams.rotation, toParams.rotation, t); | |
//Translate | |
transform.position = target.position;//Place in target position | |
Vector3 p0 = fromParams.offset; | |
Vector3 p1 = toParams.offset; | |
Vector3 p2 = Vector3.Lerp(p0, p1, t); | |
//Fix Z based on fov changes so height interpolates linearly (better interpolation on fov changes) | |
float h0 = Mathf.Tan(fromParams.fov * Mathf.Deg2Rad * 0.5f) * p0.z; | |
float h1 = Mathf.Tan(toParams.fov * Mathf.Deg2Rad * 0.5f) * p1.z; | |
float h2 = Mathf.Lerp(h0, h1, t); | |
p2.z = h2 / Mathf.Tan(cachedCamera.fieldOfView * Mathf.Deg2Rad * 0.5f); | |
transform.Translate(p2); | |
float tZ = (p1.z == p2.z) ? t : (p2.z - p0.z) / (p1.z - p0.z) ; | |
cachedCamera.nearClipPlane = Mathf.Lerp(fromParams.near, toParams.near, tZ); | |
cachedCamera.farClipPlane = Mathf.Lerp(fromParams.far, toParams.far, tZ); | |
} | |
void LateUpdate() { | |
interpolationTimeAccum = Mathf.Clamp(interpolationTimeAccum + Time.deltaTime, 0.0f, interpolationTime); | |
if(interpolationTimeAccum < interpolationTime) { | |
Refresh(); | |
} else { | |
gameObject.SetActive(false); | |
EnableComponents(toCamera, true); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment