UIVirtualJoystick.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using UnityEngine;
  2. using UnityEngine.EventSystems;
  3. using UnityEngine.Events;
  4. public class UIVirtualJoystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
  5. {
  6. [System.Serializable]
  7. public class Event : UnityEvent<Vector2> { }
  8. [Header("Rect References")]
  9. public RectTransform containerRect;
  10. public RectTransform handleRect;
  11. [Header("Settings")]
  12. public float joystickRange = 50f;
  13. public float magnitudeMultiplier = 1f;
  14. public bool invertXOutputValue;
  15. public bool invertYOutputValue;
  16. [Header("Output")]
  17. public Event joystickOutputEvent;
  18. void Start()
  19. {
  20. SetupHandle();
  21. }
  22. private void SetupHandle()
  23. {
  24. if(handleRect)
  25. {
  26. UpdateHandleRectPosition(Vector2.zero);
  27. }
  28. }
  29. public void OnPointerDown(PointerEventData eventData)
  30. {
  31. OnDrag(eventData);
  32. }
  33. public void OnDrag(PointerEventData eventData)
  34. {
  35. RectTransformUtility.ScreenPointToLocalPointInRectangle(containerRect, eventData.position, eventData.pressEventCamera, out Vector2 position);
  36. position = ApplySizeDelta(position);
  37. Vector2 clampedPosition = ClampValuesToMagnitude(position);
  38. Vector2 outputPosition = ApplyInversionFilter(position);
  39. OutputPointerEventValue(outputPosition * magnitudeMultiplier);
  40. if(handleRect)
  41. {
  42. UpdateHandleRectPosition(clampedPosition * joystickRange);
  43. }
  44. }
  45. public void OnPointerUp(PointerEventData eventData)
  46. {
  47. OutputPointerEventValue(Vector2.zero);
  48. if(handleRect)
  49. {
  50. UpdateHandleRectPosition(Vector2.zero);
  51. }
  52. }
  53. private void OutputPointerEventValue(Vector2 pointerPosition)
  54. {
  55. joystickOutputEvent.Invoke(pointerPosition);
  56. }
  57. private void UpdateHandleRectPosition(Vector2 newPosition)
  58. {
  59. handleRect.anchoredPosition = newPosition;
  60. }
  61. Vector2 ApplySizeDelta(Vector2 position)
  62. {
  63. float x = (position.x/containerRect.sizeDelta.x) * 2.5f;
  64. float y = (position.y/containerRect.sizeDelta.y) * 2.5f;
  65. return new Vector2(x, y);
  66. }
  67. Vector2 ClampValuesToMagnitude(Vector2 position)
  68. {
  69. return Vector2.ClampMagnitude(position, 1);
  70. }
  71. Vector2 ApplyInversionFilter(Vector2 position)
  72. {
  73. if(invertXOutputValue)
  74. {
  75. position.x = InvertValue(position.x);
  76. }
  77. if(invertYOutputValue)
  78. {
  79. position.y = InvertValue(position.y);
  80. }
  81. return position;
  82. }
  83. float InvertValue(float value)
  84. {
  85. return -value;
  86. }
  87. }