UIJoystick.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Events;
  5. using UnityEngine.EventSystems;
  6. public class UIJoystick : UIBehaviour
  7. {
  8. public class OnDragEvent : UnityEvent<Vector2, int> { }
  9. public Canvas canvas;
  10. public RectTransform scaleTrans;
  11. public float maxLenght = 500;
  12. public float walkToRunLength = 200;
  13. private GameObject m_ScaleGo;
  14. private bool m_LastVaildPointer = false;
  15. private bool m_VaildPointer = false;
  16. private Vector2 m_StartPos;
  17. private Vector2 m_EndPos;
  18. private OnDragEvent m_OnDragEvent = new OnDragEvent();
  19. public OnDragEvent onDragEvent
  20. {
  21. get { return m_OnDragEvent; }
  22. }
  23. protected override void Awake()
  24. {
  25. base.Awake();
  26. m_ScaleGo = scaleTrans.gameObject;
  27. m_ScaleGo.SetActive(false);
  28. }
  29. private void Update()
  30. {
  31. #if !UNITY_EDITOR && (UNITY_ANDROID || UNITY_IOS)
  32. CalcTouchDeltaPos();
  33. #else
  34. if (!CalcMouseDeltaPos())
  35. CalcKeyboardDeltaPos();
  36. #endif
  37. if (m_LastVaildPointer != m_VaildPointer)
  38. {
  39. if (m_LastVaildPointer)
  40. {
  41. m_OnDragEvent.Invoke(Vector2.zero, 0);
  42. }
  43. m_ScaleGo.SetActive(m_VaildPointer);
  44. m_LastVaildPointer = m_VaildPointer;
  45. }
  46. if (!m_VaildPointer) return;
  47. var startPos = m_StartPos;
  48. var endPos = m_EndPos;
  49. RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)this.transform, m_StartPos, canvas.worldCamera, out startPos);
  50. RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)this.transform, m_EndPos, canvas.worldCamera, out endPos);
  51. var normal = endPos - startPos;
  52. float length = normal.magnitude;
  53. normal.Normalize();
  54. if (length > maxLenght)
  55. {
  56. length = maxLenght;
  57. endPos = startPos + normal * length;
  58. // startPos = endPos - normal * length;
  59. // m_StartPos = RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, this.transform.TransformPoint(startPos));
  60. }
  61. scaleTrans.localPosition = startPos;
  62. scaleTrans.localRotation = Quaternion.FromToRotation(Vector3.up, normal);
  63. scaleTrans.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, length);
  64. if (length <= Vector2.kEpsilon)
  65. {
  66. m_OnDragEvent.Invoke(normal, 0);
  67. }
  68. else
  69. {
  70. m_OnDragEvent.Invoke(normal, (length < walkToRunLength ? 1 : 2));
  71. }
  72. }
  73. #if !UNITY_EDITOR && (UNITY_ANDROID || UNITY_IOS)
  74. private void CalcTouchDeltaPos()
  75. {
  76. if (Input.touchCount <= 0)
  77. {
  78. m_VaildPointer = false;
  79. return;
  80. }
  81. var touch = Input.GetTouch(0);
  82. if (touch.phase == TouchPhase.Began)
  83. {
  84. if (!EventSystem.current ||!EventSystem.current.IsPointerOverGameObject(touch.fingerId))
  85. {
  86. m_VaildPointer = true;
  87. m_StartPos = m_EndPos = touch.rawPosition;
  88. }
  89. return;
  90. }
  91. if (!m_VaildPointer)
  92. {
  93. return;
  94. }
  95. if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary)
  96. {
  97. m_EndPos = touch.position;
  98. }
  99. else
  100. {
  101. m_VaildPointer = false;
  102. m_StartPos = m_EndPos = Vector2.zero;
  103. }
  104. }
  105. #else
  106. private bool CalcMouseDeltaPos()
  107. {
  108. if (Input.GetMouseButtonDown(0))
  109. {
  110. if (!EventSystem.current || !EventSystem.current.IsPointerOverGameObject())
  111. {
  112. m_StartPos = m_EndPos = Input.mousePosition;
  113. m_VaildPointer = true;
  114. return true;
  115. }
  116. return false;
  117. }
  118. if (!m_VaildPointer)
  119. {
  120. return false;
  121. }
  122. if (Input.GetMouseButtonUp(0))
  123. {
  124. m_VaildPointer = false;
  125. m_StartPos = m_EndPos = Vector2.zero;
  126. return true;
  127. }
  128. if (Input.GetMouseButton(0))
  129. {
  130. m_EndPos = Input.mousePosition;
  131. return true;
  132. }
  133. return false;
  134. }
  135. private void CalcKeyboardDeltaPos()
  136. {
  137. float horizontal = Input.GetAxis("Horizontal");
  138. float vertical = Input.GetAxis("Vertical");
  139. if (Mathf.Approximately(horizontal, 0) && Mathf.Approximately(vertical, 0))
  140. {
  141. m_VaildPointer = false;
  142. m_StartPos = m_EndPos = Vector2.zero;
  143. return;
  144. }
  145. m_VaildPointer = true;
  146. m_StartPos = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f);
  147. m_EndPos = m_StartPos + new Vector2(horizontal, vertical) * maxLenght;
  148. }
  149. #endif
  150. }