Advertisement
Guest User

Untitled

a guest
Jun 17th, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.44 KB | None | 0 0
  1. using UnityEngine;
  2.  
  3. [RequireComponent(typeof(Camera))]
  4. public class GameCamera : MonoBehaviour
  5. {
  6. [Header("Runtime attributes")] [Tooltip("The point the camera is looking at")]
  7. public Transform cameraTarget;
  8.  
  9. [Tooltip("The point the camera is going to")]
  10. public Transform cameraAnchor;
  11.  
  12. [Tooltip("Setting this to true will widen the fov to 'wideFov' otherwise to 'defaultFov'")]
  13. public bool isWideMode;
  14.  
  15. [Tooltip("Setting this to false won't smooth/lerp the fov")]
  16. public bool isRotationSmoothingEnabled = true;
  17.  
  18. [Tooltip("Setting this to false won't smooth/lerp the position")]
  19. public bool isPositionSmoothingEnabled = true;
  20.  
  21. [Tooltip("Setting this to false won't smooth/lerp the rotation")]
  22. public bool isFovSmoothingEnabled = true;
  23.  
  24. [Tooltip("Setting this to false will prevent the camera from moving")]
  25. public bool lockPosition;
  26.  
  27. [Tooltip("Setting this to false will prevent the camera from rotating")]
  28. public bool lockRotation;
  29.  
  30. [Tooltip("Setting this to false will prevent the camera from changing fov")]
  31. public bool lockFov;
  32.  
  33. // ReSharper disable once MemberCanBePrivate.Global
  34. // ReSharper disable once UnusedAutoPropertyAccessor.Global
  35. /// <summary>
  36. /// This value can be used to make your GUI react to camera movement.
  37. /// </summary>
  38. /// <example>
  39. /// myGuiTransform.position = myGuiTransform.initialPosition + GameCamera.CameraScreenSpaceMotion;
  40. /// </example>
  41. public Vector2 CameraScreenSpaceMotion { get; private set; }
  42.  
  43. [Header("Configuration"), SerializeField]
  44. private UpdateMode currentUpdateMode;
  45.  
  46. [Tooltip("The time it take for the spring to bring the camera to the target position"), SerializeField]
  47. public float positionSmoothing;
  48.  
  49. [Tooltip("The time it take for the spring to bring the camera to the target rotation"), SerializeField]
  50. public float rotationSmoothing;
  51.  
  52. [Tooltip("The time it take for the spring to bring the camera to the target FOV"), SerializeField]
  53. private float fovSmooth = 1f;
  54.  
  55. [Tooltip("The amount of tilt to apply when you turn sideways"), SerializeField, Range(-1, 1)]
  56. private float cameraTilt;
  57.  
  58. [Tooltip("The FOV to use by default"), SerializeField]
  59. private float defaultFov = 75;
  60.  
  61. [Tooltip("The FOV to use when there is some action"), SerializeField]
  62. public float wideFov = 120;
  63.  
  64. private Vector3 positionVelocity;
  65. private float xAngleVelocity;
  66. private float fovVelocity;
  67. private float yAngleVelocity;
  68.  
  69. #region utils
  70.  
  71. private Camera Camera => GetComponent<Camera>();
  72. private float DeltaTime => currentUpdateMode == UpdateMode.FixedUpdate ? Time.fixedDeltaTime : Time.deltaTime;
  73. private bool IsMissingTarget => cameraTarget == null || cameraAnchor == null;
  74. private Transform self;
  75.  
  76. private void Awake()
  77. {
  78. self = transform; //Avoids regular calls to `this.transform` which is as slow as GetComponent<Transform>()
  79. }
  80.  
  81. #endregion
  82.  
  83. #region update_mode
  84.  
  85. private enum UpdateMode
  86. {
  87. Update,
  88. LateUpdate,
  89. FixedUpdate
  90. }
  91.  
  92. private void Update()
  93. {
  94. if (currentUpdateMode == UpdateMode.Update) CustomUpdate();
  95. }
  96.  
  97. private void LateUpdate()
  98. {
  99. if (currentUpdateMode == UpdateMode.LateUpdate) CustomUpdate();
  100. }
  101.  
  102. private void FixedUpdate()
  103. {
  104. if (currentUpdateMode == UpdateMode.FixedUpdate) CustomUpdate();
  105. }
  106.  
  107. #endregion
  108.  
  109.  
  110. private void CustomUpdate()
  111. {
  112. if (IsMissingTarget) return;
  113.  
  114. if (!lockPosition) UpdatePosition();
  115. if (!lockRotation) UpdateRotation();
  116. if (!lockFov) UpdateFov();
  117. }
  118.  
  119.  
  120. private void UpdateFov()
  121. {
  122. float target = isWideMode ? wideFov : defaultFov;
  123. if (isFovSmoothingEnabled) target = SmoothFov(target);
  124. Camera.fieldOfView = target;
  125. }
  126.  
  127. private void UpdateRotation()
  128. {
  129. Vector3 target = Quaternion.LookRotation(cameraTarget.transform.position - transform.position).eulerAngles;
  130. if (isRotationSmoothingEnabled) target = SmoothRotation(target);
  131. Camera.transform.rotation = Quaternion.Euler(target);
  132. }
  133.  
  134.  
  135. private void UpdatePosition()
  136. {
  137. Vector3 previous = transform.position;
  138. Vector3 target = cameraAnchor.transform.position;
  139. if (isPositionSmoothingEnabled) target = SmoothPosition(target);
  140.  
  141. self.position = target;
  142. CameraScreenSpaceMotion = target - previous;
  143. }
  144.  
  145. #region smoothing
  146.  
  147. private Vector3 SmoothRotation(Vector3 target)
  148. {
  149. Vector3 current = transform.rotation.eulerAngles;
  150. current.x = Mathf.SmoothDampAngle(current.x,
  151. target.x,
  152. ref xAngleVelocity,
  153. rotationSmoothing,
  154. float.MaxValue,
  155. DeltaTime
  156. );
  157. current.y = Mathf.SmoothDampAngle(current.y,
  158. target.y,
  159. ref yAngleVelocity,
  160. rotationSmoothing,
  161. float.MaxValue,
  162. DeltaTime
  163. );
  164. current.z = yAngleVelocity * -cameraTilt; //We never want to use z angle except for dynamic tilting
  165. return current;
  166. }
  167.  
  168. private Vector3 SmoothPosition(Vector3 target)
  169. {
  170. return Vector3.SmoothDamp(
  171. self.position,
  172. target,
  173. ref positionVelocity,
  174. positionSmoothing,
  175. float.MaxValue,
  176. DeltaTime
  177. );
  178. }
  179.  
  180. private float SmoothFov(float target)
  181. {
  182. float smoothTime = isWideMode ? fovSmooth : fovSmooth / 2f; //Fov comes back to normal twice as fast
  183. return Mathf.SmoothDamp(Camera.fieldOfView, target, ref fovVelocity, smoothTime, float.MaxValue, DeltaTime);
  184. }
  185.  
  186. #endregion
  187.  
  188. #region gizmos
  189.  
  190. private void OnDrawGizmos()
  191. {
  192. DrawGizmos(.25f, .1f);
  193. }
  194.  
  195. private void OnDrawGizmosSelected()
  196. {
  197. DrawGizmos(.75f, .2f);
  198. }
  199.  
  200. private void DrawGizmos(float alpha, float size)
  201. {
  202. if (cameraTarget != null)
  203. {
  204. Gizmos.color = new Color(0f, 1f, .5f, alpha);
  205. Gizmos.DrawSphere(cameraTarget.position, size);
  206. Gizmos.DrawLine(transform.position, cameraTarget.position);
  207. }
  208.  
  209. if (cameraAnchor != null)
  210. {
  211. Gizmos.color = new Color(0f, .5f, 1f, alpha);
  212. Gizmos.DrawSphere(cameraAnchor.position, size);
  213. Gizmos.DrawLine(transform.position, cameraAnchor.position);
  214. }
  215.  
  216. Gizmos.color = new Color(.5f, 1f, .5f, alpha);
  217. Gizmos.DrawSphere(transform.position, size);
  218. }
  219.  
  220. #endregion
  221. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement