SimpleCameraController.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #if ENABLE_INPUT_SYSTEM && ENABLE_INPUT_SYSTEM_PACKAGE
  2. #define USE_INPUT_SYSTEM
  3. using UnityEngine.InputSystem;
  4. using UnityEngine.InputSystem.Controls;
  5. #endif
  6. using UnityEngine;
  7. namespace UnityTemplateProjects
  8. {
  9. public class SimpleCameraController : MonoBehaviour
  10. {
  11. class CameraState
  12. {
  13. public float yaw;
  14. public float pitch;
  15. public float roll;
  16. public float x;
  17. public float y;
  18. public float z;
  19. public void SetFromTransform(Transform t)
  20. {
  21. pitch = t.eulerAngles.x;
  22. yaw = t.eulerAngles.y;
  23. roll = t.eulerAngles.z;
  24. x = t.position.x;
  25. y = t.position.y;
  26. z = t.position.z;
  27. }
  28. public void Translate(Vector3 translation)
  29. {
  30. Vector3 rotatedTranslation = Quaternion.Euler(pitch, yaw, roll) * translation;
  31. x += rotatedTranslation.x;
  32. y += rotatedTranslation.y;
  33. z += rotatedTranslation.z;
  34. }
  35. public void LerpTowards(CameraState target, float positionLerpPct, float rotationLerpPct)
  36. {
  37. yaw = Mathf.Lerp(yaw, target.yaw, rotationLerpPct);
  38. pitch = Mathf.Lerp(pitch, target.pitch, rotationLerpPct);
  39. roll = Mathf.Lerp(roll, target.roll, rotationLerpPct);
  40. x = Mathf.Lerp(x, target.x, positionLerpPct);
  41. y = Mathf.Lerp(y, target.y, positionLerpPct);
  42. z = Mathf.Lerp(z, target.z, positionLerpPct);
  43. }
  44. public void UpdateTransform(Transform t)
  45. {
  46. t.eulerAngles = new Vector3(pitch, yaw, roll);
  47. t.position = new Vector3(x, y, z);
  48. }
  49. }
  50. CameraState m_TargetCameraState = new CameraState();
  51. CameraState m_InterpolatingCameraState = new CameraState();
  52. [Header("Movement Settings")]
  53. [Tooltip("Exponential boost factor on translation, controllable by mouse wheel.")]
  54. public float boost = 3.5f;
  55. [Tooltip("Time it takes to interpolate camera position 99% of the way to the target."), Range(0.001f, 1f)]
  56. public float positionLerpTime = 0.2f;
  57. [Header("Rotation Settings")]
  58. [Tooltip("X = Change in mouse position.\nY = Multiplicative factor for camera rotation.")]
  59. public AnimationCurve mouseSensitivityCurve = new AnimationCurve(new Keyframe(0f, 0.5f, 0f, 5f), new Keyframe(1f, 2.5f, 0f, 0f));
  60. [Tooltip("Time it takes to interpolate camera rotation 99% of the way to the target."), Range(0.001f, 1f)]
  61. public float rotationLerpTime = 0.01f;
  62. [Tooltip("Whether or not to invert our Y axis for mouse input to rotation.")]
  63. public bool invertY = false;
  64. void OnEnable()
  65. {
  66. m_TargetCameraState.SetFromTransform(transform);
  67. m_InterpolatingCameraState.SetFromTransform(transform);
  68. }
  69. Vector3 GetInputTranslationDirection()
  70. {
  71. Vector3 direction = new Vector3();
  72. if (Input.GetKey(KeyCode.W))
  73. {
  74. direction += Vector3.forward;
  75. }
  76. if (Input.GetKey(KeyCode.S))
  77. {
  78. direction += Vector3.back;
  79. }
  80. if (Input.GetKey(KeyCode.A))
  81. {
  82. direction += Vector3.left;
  83. }
  84. if (Input.GetKey(KeyCode.D))
  85. {
  86. direction += Vector3.right;
  87. }
  88. if (Input.GetKey(KeyCode.Q))
  89. {
  90. direction += Vector3.down;
  91. }
  92. if (Input.GetKey(KeyCode.E))
  93. {
  94. direction += Vector3.up;
  95. }
  96. return direction;
  97. }
  98. void Update()
  99. {
  100. Vector3 translation = Vector3.zero;
  101. #if ENABLE_LEGACY_INPUT_MANAGER
  102. // Exit Sample
  103. if (Input.GetKey(KeyCode.Escape))
  104. {
  105. Application.Quit();
  106. #if UNITY_EDITOR
  107. UnityEditor.EditorApplication.isPlaying = false;
  108. #endif
  109. }
  110. // Hide and lock cursor when right mouse button pressed
  111. if (Input.GetMouseButtonDown(1))
  112. {
  113. Cursor.lockState = CursorLockMode.Locked;
  114. }
  115. // Unlock and show cursor when right mouse button released
  116. if (Input.GetMouseButtonUp(1))
  117. {
  118. Cursor.visible = true;
  119. Cursor.lockState = CursorLockMode.None;
  120. }
  121. // Rotation
  122. if (Input.GetMouseButton(1))
  123. {
  124. var mouseMovement = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y") * (invertY ? 1 : -1));
  125. var mouseSensitivityFactor = mouseSensitivityCurve.Evaluate(mouseMovement.magnitude);
  126. m_TargetCameraState.yaw += mouseMovement.x * mouseSensitivityFactor;
  127. m_TargetCameraState.pitch += mouseMovement.y * mouseSensitivityFactor;
  128. }
  129. // Translation
  130. translation = GetInputTranslationDirection() * Time.deltaTime;
  131. // Speed up movement when shift key held
  132. if (Input.GetKey(KeyCode.LeftShift))
  133. {
  134. translation *= 10.0f;
  135. }
  136. // Modify movement by a boost factor (defined in Inspector and modified in play mode through the mouse scroll wheel)
  137. boost += Input.mouseScrollDelta.y * 0.2f;
  138. translation *= Mathf.Pow(2.0f, boost);
  139. #elif USE_INPUT_SYSTEM
  140. // TODO: make the new input system work
  141. #endif
  142. m_TargetCameraState.Translate(translation);
  143. // Framerate-independent interpolation
  144. // Calculate the lerp amount, such that we get 99% of the way to our target in the specified time
  145. var positionLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / positionLerpTime) * Time.deltaTime);
  146. var rotationLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / rotationLerpTime) * Time.deltaTime);
  147. m_InterpolatingCameraState.LerpTowards(m_TargetCameraState, positionLerpPct, rotationLerpPct);
  148. m_InterpolatingCameraState.UpdateTransform(transform);
  149. }
  150. }
  151. }