OrbitControls.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. using Animancer.Units;
  3. using UnityEngine;
  4. namespace Animancer.Samples
  5. {
  6. /// <summary>Simple mouse controls for orbiting the camera around a focal point.</summary>
  7. /// <remarks>
  8. /// <strong>Documentation:</strong>
  9. /// <see href="https://kybernetik.com.au/animancer/docs/samples/basics/scene-setup#orbit-controls">
  10. /// Orbit Controls</see>
  11. /// </remarks>
  12. /// https://kybernetik.com.au/animancer/api/Animancer.Samples/OrbitControls
  13. ///
  14. [AddComponentMenu(Strings.SamplesMenuPrefix + "Orbit Controls")]
  15. [AnimancerHelpUrl(typeof(OrbitControls))]
  16. [ExecuteAlways]
  17. public class OrbitControls : MonoBehaviour
  18. {
  19. /************************************************************************************************************************/
  20. [SerializeField] private Transform _LookAt;
  21. [SerializeField] private Vector3 _FocalPoint = new(0, 1, 0);
  22. [SerializeField] private Vector3 _Sensitivity = new(1, -0.75f, -0.1f);
  23. [SerializeField, Meters] private float _MinZoom = 0.5f;
  24. [SerializeField, Seconds] private float _ZoomSmoothTime = 0.2f;
  25. private float _Distance;
  26. private float _TargetDistance;
  27. private float _ZoomSpeed;
  28. /************************************************************************************************************************/
  29. private Vector3 TargetPosition
  30. => _LookAt != null
  31. ? _LookAt.TransformPoint(_FocalPoint)
  32. : _FocalPoint;
  33. /************************************************************************************************************************/
  34. protected virtual void OnEnable()
  35. {
  36. Vector3 targetPosition = TargetPosition;
  37. _Distance = _TargetDistance = Vector3.Distance(targetPosition, transform.position);
  38. transform.LookAt(targetPosition);
  39. }
  40. /************************************************************************************************************************/
  41. protected virtual void Update()
  42. {
  43. #if UNITY_EDITOR
  44. if (!UnityEditor.EditorApplication.isPlaying)
  45. {
  46. transform.LookAt(TargetPosition);
  47. return;
  48. }
  49. #endif
  50. if (SampleInput.RightMouseHold)
  51. {
  52. Vector2 movement = SampleInput.MousePositionDelta;
  53. if (!movement.Equals(Vector2.zero))
  54. {
  55. Vector3 euler = transform.localEulerAngles;
  56. euler.y += movement.x * _Sensitivity.x;
  57. euler.x += movement.y * _Sensitivity.y;
  58. if (euler.x > 180)
  59. euler.x -= 360;
  60. euler.x = Mathf.Clamp(euler.x, -80, 80);
  61. transform.localEulerAngles = euler;
  62. }
  63. }
  64. // Scroll to zoom if the mouse is currently inside the game window.
  65. float zoom = SampleInput.MouseScrollDelta.y * _Sensitivity.z;
  66. Vector2 mousePosition = SampleInput.MousePosition;
  67. if (zoom != 0 &&
  68. mousePosition.x >= 0 && mousePosition.x <= Screen.width &&
  69. mousePosition.y >= 0 && mousePosition.y <= Screen.height)
  70. {
  71. if (zoom > 0)
  72. _TargetDistance *= 1 + zoom;
  73. else
  74. _TargetDistance /= 1 - zoom;
  75. if (_TargetDistance < _MinZoom)
  76. _TargetDistance = _MinZoom;
  77. }
  78. // Always update position even with no input in case the target is moving.
  79. UpdatePosition();
  80. }
  81. /************************************************************************************************************************/
  82. private void UpdatePosition()
  83. {
  84. _Distance = Mathf.SmoothDamp(_Distance, _TargetDistance, ref _ZoomSpeed, _ZoomSmoothTime);
  85. transform.position = TargetPosition - transform.forward * _Distance;
  86. }
  87. /************************************************************************************************************************/
  88. protected virtual void OnDrawGizmosSelected()
  89. {
  90. Gizmos.color = new(0.5f, 1, 0.5f, 1);
  91. Gizmos.DrawLine(transform.position, TargetPosition);
  92. }
  93. /************************************************************************************************************************/
  94. }
  95. }