DragMe.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4. using UnityEngine.UI;
  5. using Rokid.UXR.Interaction;
  6. namespace Rokid.UXR.Demo
  7. {
  8. [RequireComponent(typeof(Image))]
  9. public class DragMe : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
  10. {
  11. public bool dragOnSurfaces = true;
  12. private Dictionary<int, GameObject> m_DraggingIcons = new Dictionary<int, GameObject>();
  13. private Dictionary<int, RectTransform> m_DraggingPlanes = new Dictionary<int, RectTransform>();
  14. [SerializeField]
  15. private int pointerId;
  16. public void OnBeginDrag(PointerEventData eventData)
  17. {
  18. RKLog.Debug($"====DragMe====: OnBeginDrag");
  19. var canvas = FindInParents<Canvas>(gameObject);
  20. if (canvas == null)
  21. return;
  22. if (pointerId != 0)
  23. return;
  24. this.pointerId = eventData.pointerId;
  25. // We have clicked something that can be dragged.
  26. // What we want to do is create an icon for this.
  27. m_DraggingIcons[eventData.pointerId] = new GameObject("icon");
  28. m_DraggingIcons[eventData.pointerId].transform.SetParent(canvas.transform, false);
  29. m_DraggingIcons[eventData.pointerId].transform.SetAsLastSibling();
  30. var image = m_DraggingIcons[eventData.pointerId].AddComponent<Image>();
  31. // The icon will be under the cursor.
  32. // We want it to be ignored by the event system.
  33. var group = m_DraggingIcons[eventData.pointerId].AddComponent<CanvasGroup>();
  34. group.blocksRaycasts = false;
  35. image.sprite = GetComponent<Image>().sprite;
  36. image.color = GetComponent<Image>().color;
  37. image.transform.localScale = Vector3.one * 0.3f;
  38. image.SetNativeSize();
  39. if (dragOnSurfaces)
  40. m_DraggingPlanes[eventData.pointerId] = transform as RectTransform;
  41. else
  42. m_DraggingPlanes[eventData.pointerId] = canvas.transform as RectTransform;
  43. SetDraggedPosition(eventData);
  44. }
  45. public void OnDrag(PointerEventData eventData)
  46. {
  47. if (m_DraggingIcons[eventData.pointerId] != null)
  48. SetDraggedPosition(eventData);
  49. }
  50. private void SetDraggedPosition(PointerEventData eventData)
  51. {
  52. if (dragOnSurfaces && eventData.pointerEnter != null && eventData.pointerEnter.transform as RectTransform != null)
  53. m_DraggingPlanes[eventData.pointerId] = eventData.pointerEnter.transform as RectTransform;
  54. var rt = m_DraggingIcons[eventData.pointerId].GetComponent<RectTransform>();
  55. Vector3 globalMousePos;
  56. if (ScreenPointToWorldPointInRectangle(m_DraggingPlanes[eventData.pointerId], out globalMousePos))
  57. {
  58. rt.position = globalMousePos;
  59. rt.rotation = m_DraggingPlanes[eventData.pointerId].rotation;
  60. }
  61. }
  62. public bool ScreenPointToWorldPointInRectangle(RectTransform rect, out Vector3 worldPoint)
  63. {
  64. worldPoint = Vector2.zero;
  65. Ray ray = RayInteractor.GetRayByIdentifier(pointerId);
  66. Plane plane = new Plane(rect.rotation * Vector3.back, rect.position);
  67. float enter = 0f;
  68. float num = Vector3.Dot(Vector3.Normalize(rect.position - ray.origin), plane.normal);
  69. if (num != 0f && !plane.Raycast(ray, out enter))
  70. {
  71. return false;
  72. }
  73. worldPoint = ray.GetPoint(enter);
  74. return true;
  75. }
  76. public void OnEndDrag(PointerEventData eventData)
  77. {
  78. if (m_DraggingIcons[eventData.pointerId] != null)
  79. Destroy(m_DraggingIcons[eventData.pointerId]);
  80. m_DraggingIcons[eventData.pointerId] = null;
  81. this.pointerId = 0;
  82. }
  83. static public T FindInParents<T>(GameObject go) where T : Component
  84. {
  85. if (go == null) return null;
  86. var comp = go.GetComponent<T>();
  87. if (comp != null)
  88. return comp;
  89. var t = go.transform.parent;
  90. while (t != null && comp == null)
  91. {
  92. comp = t.gameObject.GetComponent<T>();
  93. t = t.parent;
  94. }
  95. return comp;
  96. }
  97. }
  98. }