AroundCamera.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. 
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4. using UnityEngine.UI;
  5. /// <summary>
  6. /// </summary> [RequireComponent(typeof(Camera))]
  7. public class AroundCamera : MonoBehaviour
  8. {
  9. #region Field and Property
  10. /// <summary>
  11. /// Around center.
  12. /// </summary>
  13. public Transform target;
  14. /// <summary>
  15. /// Settings of mouse button, pointer and scrollwheel.
  16. /// </summary>
  17. public MouseSettings mouseSettings = new MouseSettings(1, 10, 10);
  18. /// <summary>
  19. /// Range limit of angle.
  20. /// </summary>
  21. public Range angleRange = new Range(-90, 90);
  22. /// <summary>
  23. /// Range limit of distance.
  24. /// </summary>
  25. public Range distanceRange = new Range(1, 10);
  26. /// <summary>
  27. /// Damper for move and rotate.
  28. /// </summary>
  29. [Range(0, 10)]
  30. public float damper = 5;
  31. /// <summary>
  32. /// Camera current angls.
  33. /// </summary>
  34. public Vector2 CurrentAngles { set; get; }
  35. /// <summary>
  36. /// Current distance from camera to target.
  37. /// </summary>
  38. public float CurrentDistance { set; get; }
  39. /// <summary>
  40. /// Camera target angls.
  41. /// </summary>
  42. public Vector2 targetAngles;
  43. /// <summary>
  44. /// Target distance from camera to target.
  45. /// </summary>
  46. public float targetDistance;
  47. public int mLayer;
  48. public bool mIsMovableDetection = true;
  49. public bool mRotateEnable = true;
  50. public static bool mIsTouchedUI = false;
  51. #endregion
  52. #region Protected Method
  53. protected virtual void Start()
  54. {
  55. Initialize();
  56. }
  57. private void Update()
  58. {
  59. if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1))
  60. {
  61. if (EventSystem.current.IsPointerOverGameObject())
  62. {
  63. mIsTouchedUI = true;
  64. }
  65. }
  66. if(Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(1))
  67. {
  68. mIsTouchedUI = false;
  69. }
  70. }
  71. public static bool IsTouchedUI()
  72. {
  73. return mIsTouchedUI;
  74. }
  75. public float mCameraDistance = 0.0f;
  76. protected virtual void LateUpdate()
  77. {
  78. Ray ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward);
  79. RaycastHit hit;
  80. if (Physics.Raycast(ray, out hit, float.MaxValue))
  81. {
  82. float cameraDistance = Vector3.Distance(Camera.main.transform.position, hit.point);
  83. mouseSettings.wheelSensitivity = cameraDistance / 4;
  84. mCameraDistance = cameraDistance;
  85. }
  86. AroundByMouse();
  87. }
  88. /// <summary>
  89. /// Initialize component.
  90. /// </summary>
  91. public virtual void Initialize()
  92. {
  93. CurrentAngles = targetAngles = transform.eulerAngles;
  94. CurrentDistance = targetDistance = Vector3.Distance(transform.position, target.position);
  95. }
  96. /// <summary>
  97. /// Camera around target by mouse.
  98. /// </summary>
  99. public void AroundByMouse()
  100. {
  101. if (IsTouchedUI()) return;
  102. float preDistance = targetDistance;
  103. Vector2 preAngle = targetAngles;
  104. bool mouseOperate = false;
  105. #if !UNITY_ANDROID
  106. if (Input.GetMouseButton(mouseSettings.mouseButtonID) && !IsTouchedUI())
  107. {
  108. //Mouse pointer.
  109. targetAngles.y += Input.GetAxis("Mouse X") * mouseSettings.pointerSensitivity;
  110. targetAngles.x -= Input.GetAxis("Mouse Y") * mouseSettings.pointerSensitivity;
  111. //Range.
  112. targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max);
  113. mouseOperate = true;
  114. }
  115. if (Input.GetAxis("Mouse ScrollWheel") != 0f)
  116. {
  117. //Mouse scrollwheel.
  118. targetDistance -= Input.GetAxis("Mouse ScrollWheel") * mouseSettings.wheelSensitivity;
  119. targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max);
  120. mouseOperate = true;
  121. }
  122. #else
  123. if (Input.touchCount == 2)
  124. {
  125. Touch touch0 = Input.GetTouch(0);
  126. Touch touch1 = Input.GetTouch(1);
  127. if (touch0.phase == TouchPhase.Moved && touch1.phase == TouchPhase.Moved)
  128. {
  129. Vector2 lastDelta = (touch0.position - touch0.deltaPosition) - (touch1.position - touch1.deltaPosition);
  130. Vector2 currDelta = touch0.position - touch1.position;
  131. float deltaMagnitude = currDelta.magnitude - lastDelta.magnitude;
  132. targetDistance -= deltaMagnitude * mouseSettings.wheelSensitivity * 0.02f;
  133. targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max);
  134. CurrentDistance = targetDistance;
  135. mouseOperate = true;
  136. }
  137. }
  138. if (Input.touchCount == 1 && mRotateEnable)
  139. {
  140. //Mouse pointer.
  141. targetAngles.y += Input.GetAxis("Mouse X") * mouseSettings.pointerSensitivity * 0.2f; ;
  142. targetAngles.x -= Input.GetAxis("Mouse Y") * mouseSettings.pointerSensitivity * 0.2f; ;
  143. //Range.
  144. targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max);
  145. CurrentAngles = targetAngles;
  146. mouseOperate = true;
  147. }
  148. #endif
  149. if (mouseOperate && !MovableDetection())
  150. {
  151. targetDistance = preDistance;
  152. targetAngles = preAngle;
  153. return;
  154. }
  155. #if !UNITY_ANDROID
  156. //Lerp.
  157. CurrentAngles = Vector2.Lerp(CurrentAngles, targetAngles, damper * Time.deltaTime);
  158. CurrentDistance = Mathf.Lerp(CurrentDistance, targetDistance, damper * Time.deltaTime);
  159. //Not Lerp
  160. //CurrentAngles = targetAngles;
  161. //CurrentDistance = targetDistance;
  162. #endif
  163. //Update transform position and rotation.
  164. transform.rotation = Quaternion.Euler(CurrentAngles);
  165. transform.position = target.position - transform.forward * CurrentDistance;
  166. #region
  167. #if !UNITY_ANDROID
  168. if (Vector2.Distance(CurrentAngles, targetAngles) > 1.0f)
  169. PlayerPrefs.SetInt("CameraRotating", 1);
  170. else
  171. PlayerPrefs.SetInt("CameraRotating", 0);
  172. if (Mathf.Abs(CurrentDistance - targetDistance) > 1.0f)
  173. PlayerPrefs.SetInt("CameraZooming", 1);
  174. else
  175. PlayerPrefs.SetInt("CameraZooming", 0);
  176. #endif
  177. #endregion
  178. }
  179. public bool MovableDetection()
  180. {
  181. if (!mIsMovableDetection) return true;
  182. Quaternion preRot = transform.rotation;
  183. Vector3 prePos = transform.position;
  184. transform.rotation = Quaternion.Euler(targetAngles);
  185. transform.position = target.position - transform.forward * targetDistance;
  186. if (Physics.Linecast(prePos, transform.position))
  187. {
  188. transform.rotation = preRot;
  189. transform.position = prePos;
  190. return false;
  191. }
  192. return true;
  193. }
  194. #endregion
  195. }