SimpleCameraControllerV2.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. using UnityEngine;
  2. using UnityEngine.InputSystem;
  3. using UnityEngine.InputSystem.EnhancedTouch;
  4. namespace Unity.RenderStreaming.Samples
  5. {
  6. class SimpleCameraControllerV2 : MonoBehaviour
  7. {
  8. class CameraState
  9. {
  10. public float yaw;
  11. public float pitch;
  12. public float roll;
  13. public float x;
  14. public float y;
  15. public float z;
  16. public void SetFromTransform(Transform t)
  17. {
  18. pitch = t.eulerAngles.x;
  19. yaw = t.eulerAngles.y;
  20. roll = t.eulerAngles.z;
  21. x = t.position.x;
  22. y = t.position.y;
  23. z = t.position.z;
  24. }
  25. public void Translate(Vector3 translation)
  26. {
  27. Vector3 rotatedTranslation = Quaternion.Euler(pitch, yaw, roll) * translation;
  28. x += rotatedTranslation.x;
  29. y += rotatedTranslation.y;
  30. z += rotatedTranslation.z;
  31. }
  32. public void LerpTowards(CameraState target, float positionLerpPct, float rotationLerpPct)
  33. {
  34. yaw = Mathf.Lerp(yaw, target.yaw, rotationLerpPct);
  35. pitch = Mathf.Lerp(pitch, target.pitch, rotationLerpPct);
  36. roll = Mathf.Lerp(roll, target.roll, rotationLerpPct);
  37. x = Mathf.Lerp(x, target.x, positionLerpPct);
  38. y = Mathf.Lerp(y, target.y, positionLerpPct);
  39. z = Mathf.Lerp(z, target.z, positionLerpPct);
  40. }
  41. public void UpdateTransform(Transform t)
  42. {
  43. t.eulerAngles = new Vector3(pitch, yaw, roll);
  44. t.position = new Vector3(x, y, z);
  45. }
  46. }
  47. [Header("Movement Settings"), Tooltip("Movement Sensitivity Factor."), Range(0.001f, 1f), SerializeField]
  48. private float movementSensitivityFactor = 0.1f;
  49. [Tooltip("Exponential boost factor on translation, controllable by mouse wheel."), SerializeField]
  50. private float boost = 3.5f;
  51. [Tooltip("Time it takes to interpolate camera position 99% of the way to the target."), Range(0.001f, 1f),
  52. SerializeField]
  53. private float positionLerpTime = 0.2f;
  54. [Header("Rotation Settings"),
  55. Tooltip("X = Change in mouse position.\nY = Multiplicative factor for camera rotation."), SerializeField]
  56. private AnimationCurve mouseSensitivityCurve =
  57. new AnimationCurve(new Keyframe(0f, 0.5f, 0f, 5f), new Keyframe(1f, 2.5f, 0f, 0f));
  58. [Tooltip("Time it takes to interpolate camera rotation 99% of the way to the target."), Range(0.001f, 1f),
  59. SerializeField]
  60. private float rotationLerpTime = 0.01f;
  61. [Tooltip("Whether or not to invert our Y axis for mouse input to rotation."), SerializeField]
  62. private bool invertY;
  63. [SerializeField] InputReceiver playerInput;
  64. private readonly CameraState m_TargetCameraState = new CameraState();
  65. private readonly CameraState m_InterpolatingCameraState = new CameraState();
  66. private readonly CameraState m_InitialCameraState = new CameraState();
  67. Vector2 inputMovement;
  68. Vector2 inputLook;
  69. Vector3? inputPosition;
  70. Quaternion? inputRotation;
  71. protected void Awake()
  72. {
  73. playerInput.onDeviceChange += OnDeviceChange;
  74. m_InitialCameraState.SetFromTransform(transform);
  75. // Need to set enable the flag to receive touch screen event from mobile devices.
  76. EnhancedTouchSupport.Enable();
  77. }
  78. void OnDeviceChange(InputDevice device, InputDeviceChange change)
  79. {
  80. switch (change)
  81. {
  82. case InputDeviceChange.Added:
  83. {
  84. playerInput.PerformPairingWithDevice(device);
  85. return;
  86. }
  87. case InputDeviceChange.Removed:
  88. {
  89. playerInput.UnpairDevices(device);
  90. return;
  91. }
  92. }
  93. }
  94. private void OnEnable()
  95. {
  96. m_TargetCameraState.SetFromTransform(transform);
  97. m_InterpolatingCameraState.SetFromTransform(transform);
  98. }
  99. private void FixedUpdate()
  100. {
  101. // Tracked Device
  102. if(inputPosition.HasValue && inputRotation.HasValue)
  103. {
  104. transform.position = inputPosition.Value;
  105. transform.rotation = inputRotation.Value;
  106. return;
  107. }
  108. UpdateTargetCameraStateDirection(inputMovement);
  109. UpdateTargetCameraStateFromInput(inputLook);
  110. // Framerate-independent interpolation
  111. // Calculate the lerp amount, such that we get 99% of the way to our target in the specified time
  112. var positionLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / positionLerpTime) * Time.deltaTime);
  113. var rotationLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / rotationLerpTime) * Time.deltaTime);
  114. m_InterpolatingCameraState.LerpTowards(m_TargetCameraState, positionLerpPct, rotationLerpPct);
  115. m_InterpolatingCameraState.UpdateTransform(transform);
  116. }
  117. private void UpdateTargetCameraStateDirection(Vector2 input)
  118. {
  119. if (!invertY)
  120. {
  121. input.y *= -1;
  122. }
  123. var translation = Vector3.right * input.x * movementSensitivityFactor;
  124. translation += Vector3.back * input.y * movementSensitivityFactor;
  125. translation *= Mathf.Pow(2.0f, boost);
  126. m_TargetCameraState.Translate(translation);
  127. }
  128. private void UpdateTargetCameraStateFromInput(Vector2 input)
  129. {
  130. if (!invertY)
  131. {
  132. input.y *= -1;
  133. }
  134. float mouseSensitivityFactor = mouseSensitivityCurve.Evaluate(input.magnitude);
  135. m_TargetCameraState.yaw += input.x * mouseSensitivityFactor;
  136. m_TargetCameraState.pitch += input.y * mouseSensitivityFactor;
  137. }
  138. public void OnControlsChanged()
  139. {
  140. }
  141. public void OnDeviceLost()
  142. {
  143. }
  144. public void OnDeviceRegained()
  145. {
  146. }
  147. public void OnMovement(InputAction.CallbackContext context)
  148. {
  149. inputMovement = context.ReadValue<Vector2>();
  150. }
  151. public void OnLook(InputAction.CallbackContext context)
  152. {
  153. inputLook = context.ReadValue<Vector2>();
  154. }
  155. public void OnResetCamera(InputAction.CallbackContext context)
  156. {
  157. m_InitialCameraState.UpdateTransform(transform);
  158. m_TargetCameraState.SetFromTransform(transform);
  159. m_InterpolatingCameraState.SetFromTransform(transform);
  160. }
  161. public void OnPosition(InputAction.CallbackContext context)
  162. {
  163. inputPosition = context.ReadValue<Vector3>();
  164. }
  165. public void OnRotate(InputAction.CallbackContext context)
  166. {
  167. inputRotation = context.ReadValue<Quaternion>();
  168. }
  169. }
  170. }