Advertisement
Learning000001

Untitled

Feb 12th, 2025
7
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.21 KB | None | 0 0
  1. using System.Collections;
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4. using UnityEngine.Events;
  5.  
  6. public class DraggableHandler : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
  7. {
  8. [SerializeField] private RectTransform objectHolder;
  9. [SerializeField] private int dragMargin;
  10. [SerializeField] private UnityEvent onDragComplete;
  11. [SerializeField] private UnityEvent onExitScreen;
  12. [SerializeField] private UnityEvent onDragLessThenMargin;
  13.  
  14. private Vector2 startingPosition;
  15. private Vector2 startingClickPosition;
  16. private bool isDragging;
  17. private Canvas parentCanvas;
  18. private RectTransform canvasRectTransform;
  19. private Vector2 dragOffset;
  20. private Vector2 lastPointerPosition;
  21. private bool isAnimating;
  22.  
  23. private void Awake()
  24. {
  25. InitializeComponents();
  26. }
  27.  
  28. private void InitializeComponents()
  29. {
  30. startingPosition = objectHolder.anchoredPosition;
  31. parentCanvas = GetComponentInParent<Canvas>();
  32. canvasRectTransform = parentCanvas.GetComponent<RectTransform>();
  33. }
  34.  
  35. public void OnBeginDrag(PointerEventData _eventData)
  36. {
  37. if (isAnimating)
  38. {
  39. return;
  40. }
  41. isDragging = true;
  42. startingClickPosition = _eventData.position;
  43. lastPointerPosition = GetLocalPoint(_eventData.position);
  44. dragOffset = objectHolder.anchoredPosition - lastPointerPosition;
  45. }
  46.  
  47. public void OnEndDrag(PointerEventData _eventData)
  48. {
  49. if (!isDragging)
  50. {
  51. return;
  52. }
  53.  
  54. isDragging = false;
  55. var _distanceDragged = Mathf.Abs(startingClickPosition.y - _eventData.position.y);
  56. if (_distanceDragged<=dragMargin)
  57. {
  58. StartCoroutine(AnimateBackToStartingPosition());
  59. }
  60. else
  61. {
  62. onDragComplete?.Invoke();
  63. }
  64. }
  65.  
  66. private IEnumerator AnimateBackToStartingPosition(float _duration = 0.1f)
  67. {
  68. float _elapsed = 0f;
  69. Vector2 _currentPos = objectHolder.anchoredPosition;
  70. isAnimating = true;
  71. while (_elapsed < _duration)
  72. {
  73. objectHolder.anchoredPosition = Vector2.Lerp(_currentPos, startingPosition, _elapsed / _duration);
  74. _elapsed += Time.deltaTime;
  75. yield return null;
  76. }
  77. isAnimating = false;
  78.  
  79. objectHolder.anchoredPosition = startingPosition;
  80. }
  81.  
  82.  
  83. public void OnDrag(PointerEventData _eventData)
  84. {
  85. if (!isDragging)
  86. {
  87. return;
  88. }
  89.  
  90. SetNewPosition(_eventData);
  91. CheckScreenVisibility();
  92. }
  93.  
  94. private void SetNewPosition(PointerEventData _eventData)
  95. {
  96. Vector2 _localPoint = GetLocalPoint(_eventData.position);
  97. lastPointerPosition = _localPoint;
  98.  
  99. float _newY = Mathf.Min((_localPoint + dragOffset).y, startingPosition.y);
  100. objectHolder.anchoredPosition = new Vector2(objectHolder.anchoredPosition.x, _newY);
  101. }
  102.  
  103. private Vector2 GetLocalPoint(Vector2 _position)
  104. {
  105. Camera _camera = parentCanvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : parentCanvas.worldCamera;
  106. RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRectTransform, _position, _camera, out Vector2 _localPoint);
  107.  
  108. return _localPoint;
  109. }
  110.  
  111. private void CheckScreenVisibility()
  112. {
  113. if (IsObjectVisible())
  114. {
  115. return;
  116. }
  117.  
  118. isDragging = false;
  119. onExitScreen?.Invoke();
  120. }
  121.  
  122. private bool IsObjectVisible()
  123. {
  124. Vector3[] _corners = new Vector3[4];
  125. objectHolder.GetWorldCorners(_corners);
  126.  
  127. Camera _camera = parentCanvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : parentCanvas.worldCamera;
  128. Rect _screenRect = new Rect(0, 0, Screen.width, Screen.height);
  129.  
  130. foreach (var _corner in _corners)
  131. {
  132. Vector3 _screenPoint = _camera ? _camera.WorldToScreenPoint(_corner) : _corner;
  133. if (_screenRect.Contains(new Vector2(_screenPoint.x, _screenPoint.y)))
  134. {
  135. return true;
  136. }
  137. }
  138.  
  139. return false;
  140. }
  141. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement