OrbitMotion.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using UnityEngine;
  2. namespace Dustyroom {
  3. public class OrbitMotion : MonoBehaviour {
  4. public enum TargetMode {
  5. Transform,
  6. Position
  7. }
  8. public TargetMode targetMode = TargetMode.Position;
  9. public Transform targetTransform;
  10. public bool followTargetTransform = true;
  11. public Vector3 targetOffset = Vector3.zero;
  12. public Vector3 targetPosition;
  13. [Space] public float distanceHorizontal = 60.0f;
  14. public float distanceVertical = 60.0f;
  15. public float xSpeed = 120.0f;
  16. public float ySpeed = 120.0f;
  17. public float damping = 3f;
  18. [Space] public bool clampAngle = false;
  19. public float yMinLimit = -20f;
  20. public float yMaxLimit = 80f;
  21. [Space] public bool allowZoom = false;
  22. public float distanceMin = .5f;
  23. public float distanceMax = 15f;
  24. float _x = 0.0f;
  25. float _y = 0.0f;
  26. [Space] public bool autoMovement = false;
  27. public float autoSpeedX = 0.2f;
  28. public float autoSpeedY = 0.1f;
  29. public float autoSpeedDistance = -0.1f;
  30. [Space] public bool interactive = true;
  31. private float _lastMoveTime;
  32. [HideInInspector] public float timeSinceLastMove;
  33. void Start() {
  34. Vector3 angles = transform.eulerAngles;
  35. _x = angles.y;
  36. _y = angles.x;
  37. // Make the rigid body not change rotation
  38. Rigidbody rigidbody = GetComponent<Rigidbody>();
  39. if (rigidbody != null) {
  40. rigidbody.freezeRotation = true;
  41. }
  42. #if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
  43. xSpeed *= 0.2f;
  44. ySpeed *= 0.2f;
  45. #endif
  46. if (targetMode == TargetMode.Transform) {
  47. if (targetTransform != null) {
  48. targetPosition = targetTransform.position + targetOffset;
  49. }
  50. else {
  51. Debug.LogWarning("Reference transform is not set.");
  52. }
  53. }
  54. }
  55. void Update() {
  56. if (targetMode == TargetMode.Transform && followTargetTransform) {
  57. if (targetTransform != null) {
  58. targetPosition = targetTransform.position + targetOffset;
  59. }
  60. else {
  61. Debug.LogWarning("Reference transform is not set.");
  62. }
  63. }
  64. //*
  65. bool isCameraMoving = false;
  66. #if ((UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR)
  67. isCameraMoving = Input.GetTouch(0).deltaPosition.sqrMagnitude > 0f;
  68. #else
  69. isCameraMoving = Mathf.Abs(Input.GetAxis("Mouse X")) + Mathf.Abs(Input.GetAxis("Mouse Y")) > 0f;
  70. #endif
  71. if (isCameraMoving) {
  72. _lastMoveTime = Time.time;
  73. }
  74. timeSinceLastMove = Time.time - _lastMoveTime;
  75. //*/
  76. if (interactive && Input.GetMouseButton(0)) {
  77. #if ((UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR)
  78. _x += Input.GetTouch(0).deltaPosition.x * xSpeed * 40f * 0.02f;
  79. _y -= Input.GetTouch(0).deltaPosition.y * ySpeed * 40f * 0.02f;
  80. #else
  81. _x += Input.GetAxis("Mouse X") * xSpeed * 40f * 0.02f;
  82. _y -= Input.GetAxis("Mouse Y") * ySpeed * 40f * 0.02f;
  83. #endif
  84. }
  85. else if (autoMovement) {
  86. _x += autoSpeedX * 40f * Time.deltaTime * 10f;
  87. _y -= autoSpeedY * 40f * Time.deltaTime * 10f;
  88. distanceHorizontal += autoSpeedDistance;
  89. }
  90. if (clampAngle) {
  91. _y = ClampAngle(_y, yMinLimit, yMaxLimit);
  92. }
  93. Quaternion rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(_y, _x, 0),
  94. Time.deltaTime * damping);
  95. if (allowZoom) {
  96. distanceHorizontal = Mathf.Clamp(
  97. distanceHorizontal - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);
  98. }
  99. float rotationX = rotation.eulerAngles.x;
  100. if (rotationX > 90f) {
  101. rotationX -= 360f;
  102. }
  103. float usedDistance = Mathf.Lerp(distanceHorizontal, distanceVertical, Mathf.Abs(rotationX / 90f));
  104. Vector3 negDistance = new Vector3(0.0f, 0.0f, -usedDistance);
  105. Vector3 position = rotation * negDistance + targetPosition;
  106. transform.rotation = rotation;
  107. transform.position = position;
  108. }
  109. private static float ClampAngle(float angle, float min, float max) {
  110. if (angle < -360f)
  111. angle += 360f;
  112. if (angle > 360f)
  113. angle -= 360f;
  114. return Mathf.Clamp(angle, min, max);
  115. }
  116. }
  117. }