2021년 4학년 1학기 기업연계프로젝트2 컴퓨터소프트웨어공학과 <원광투어팀> 팀장 : 송유진 팀원 : 김나영, 이경희, 한유진
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
7.2 KiB

5 years ago
  1. using HTC.UnityPlugin.Utility;
  2. using HTC.UnityPlugin.Vive;
  3. using System;
  4. using UnityEngine;
  5. using UnityEngine.Events;
  6. using UnityEngine.EventSystems;
  7. using UnityEngine.Serialization;
  8. using GrabberPool = HTC.UnityPlugin.Utility.ObjectPool<Draggable.Grabber>;
  9. // demonstrate of dragging things useing built in EventSystem handlers
  10. public class Draggable : GrabbableBase<Draggable.Grabber>
  11. , IInitializePotentialDragHandler
  12. , IBeginDragHandler
  13. , IDragHandler
  14. , IEndDragHandler
  15. {
  16. [Serializable]
  17. public class UnityEventDraggable : UnityEvent<Draggable> { }
  18. public class Grabber : IGrabber
  19. {
  20. private static GrabberPool m_pool;
  21. public static Grabber Get(PointerEventData eventData)
  22. {
  23. if (m_pool == null)
  24. {
  25. m_pool = new GrabberPool(() => new Grabber());
  26. }
  27. var grabber = m_pool.Get();
  28. grabber.eventData = eventData;
  29. return grabber;
  30. }
  31. public static void Release(Grabber grabber)
  32. {
  33. grabber.eventData = null;
  34. m_pool.Release(grabber);
  35. }
  36. public PointerEventData eventData { get; private set; }
  37. public RigidPose grabberOrigin
  38. {
  39. get
  40. {
  41. var cam = eventData.pointerPressRaycast.module.eventCamera;
  42. var ray = cam.ScreenPointToRay(eventData.position);
  43. return new RigidPose(ray.origin, Quaternion.LookRotation(ray.direction, cam.transform.up));
  44. }
  45. }
  46. public RigidPose grabOffset { get { return grabber2hit * hit2pivot; } set { } }
  47. public RigidPose grabber2hit { get; set; }
  48. public RigidPose hit2pivot { get; set; }
  49. public float hitDistance
  50. {
  51. get { return grabber2hit.pos.z; }
  52. set
  53. {
  54. var p = grabber2hit;
  55. p.pos.z = value;
  56. grabber2hit = p;
  57. }
  58. }
  59. }
  60. private IndexedTable<PointerEventData, Grabber> m_eventGrabberSet;
  61. [FormerlySerializedAs("initGrabDistance")]
  62. [SerializeField]
  63. private float m_initGrabDistance = 0.5f;
  64. [Range(MIN_FOLLOWING_DURATION, MAX_FOLLOWING_DURATION)]
  65. [FormerlySerializedAs("followingDuration")]
  66. [SerializeField]
  67. private float m_followingDuration = DEFAULT_FOLLOWING_DURATION;
  68. [FormerlySerializedAs("overrideMaxAngularVelocity")]
  69. [SerializeField]
  70. private bool m_overrideMaxAngularVelocity = true;
  71. [FormerlySerializedAs("unblockableGrab")]
  72. [SerializeField]
  73. private bool m_unblockableGrab = true;
  74. [FormerlySerializedAs("afterGrabbed")]
  75. [SerializeField]
  76. private UnityEventDraggable m_afterGrabbed = new UnityEventDraggable();
  77. [FormerlySerializedAs("beforeRelease")]
  78. [SerializeField]
  79. private UnityEventDraggable m_beforeRelease = new UnityEventDraggable();
  80. [FormerlySerializedAs("onDrop")]
  81. [SerializeField]
  82. private UnityEventDraggable m_onDrop = new UnityEventDraggable(); // change rigidbody drop velocity here
  83. [SerializeField]
  84. [FormerlySerializedAs("m_scrollDelta")]
  85. private float m_scrollingSpeed = 0.01f;
  86. public bool isDragged { get { return isGrabbed; } }
  87. public PointerEventData draggedEvent { get { return isGrabbed ? currentGrabber.eventData : null; } }
  88. public float initGrabDistance { get { return m_initGrabDistance; } set { m_initGrabDistance = value; } }
  89. public override float followingDuration { get { return m_followingDuration; } set { m_followingDuration = Mathf.Clamp(value, MIN_FOLLOWING_DURATION, MAX_FOLLOWING_DURATION); } }
  90. public override bool overrideMaxAngularVelocity { get { return m_overrideMaxAngularVelocity; } set { m_overrideMaxAngularVelocity = value; } }
  91. public bool unblockableGrab { get { return m_unblockableGrab; } set { m_unblockableGrab = value; } }
  92. public UnityEventDraggable afterGrabbed { get { return m_afterGrabbed; } }
  93. public UnityEventDraggable beforeRelease { get { return m_beforeRelease; } }
  94. public UnityEventDraggable onDrop { get { return m_onDrop; } }
  95. private bool moveByVelocity { get { return !unblockableGrab && grabRigidbody != null && !grabRigidbody.isKinematic; } }
  96. [Obsolete("Use grabRigidbody instead")]
  97. public Rigidbody rigid { get { return grabRigidbody; } set { grabRigidbody = value; } }
  98. public float scrollingSpeed { get { return m_scrollingSpeed; } set { m_scrollingSpeed = value; } }
  99. protected override void Awake()
  100. {
  101. base.Awake();
  102. afterGrabberGrabbed += () => m_afterGrabbed.Invoke(this);
  103. beforeGrabberReleased += () => m_beforeRelease.Invoke(this);
  104. onGrabberDrop += () => m_onDrop.Invoke(this);
  105. }
  106. protected virtual void OnDisable()
  107. {
  108. ClearGrabbers(true);
  109. ClearEventGrabberSet();
  110. }
  111. private void ClearEventGrabberSet()
  112. {
  113. if (m_eventGrabberSet == null) { return; }
  114. for (int i = m_eventGrabberSet.Count - 1; i >= 0; --i)
  115. {
  116. Grabber.Release(m_eventGrabberSet.GetValueByIndex(i));
  117. }
  118. m_eventGrabberSet.Clear();
  119. }
  120. public virtual void OnInitializePotentialDrag(PointerEventData eventData)
  121. {
  122. eventData.useDragThreshold = false;
  123. }
  124. public virtual void OnBeginDrag(PointerEventData eventData)
  125. {
  126. var hitDistance = 0f;
  127. switch (eventData.button)
  128. {
  129. case PointerEventData.InputButton.Middle:
  130. case PointerEventData.InputButton.Right:
  131. hitDistance = Mathf.Min(eventData.pointerPressRaycast.distance, m_initGrabDistance);
  132. break;
  133. case PointerEventData.InputButton.Left:
  134. hitDistance = eventData.pointerPressRaycast.distance;
  135. break;
  136. default:
  137. return;
  138. }
  139. var grabber = Grabber.Get(eventData);
  140. grabber.grabber2hit = new RigidPose(new Vector3(0f, 0f, hitDistance), Quaternion.identity);
  141. grabber.hit2pivot = RigidPose.FromToPose(grabber.grabberOrigin * grabber.grabber2hit, new RigidPose(transform));
  142. if (m_eventGrabberSet == null) { m_eventGrabberSet = new IndexedTable<PointerEventData, Grabber>(); }
  143. m_eventGrabberSet.Add(eventData, grabber);
  144. AddGrabber(grabber);
  145. }
  146. protected virtual void FixedUpdate()
  147. {
  148. if (isGrabbed && moveByVelocity)
  149. {
  150. OnGrabRigidbody();
  151. }
  152. }
  153. protected virtual void Update()
  154. {
  155. if (!isGrabbed) { return; }
  156. if (!moveByVelocity)
  157. {
  158. RecordLatestPosesForDrop(Time.time, 0.05f);
  159. OnGrabTransform();
  160. }
  161. var scrollDelta = currentGrabber.eventData.scrollDelta * m_scrollingSpeed;
  162. if (scrollDelta != Vector2.zero)
  163. {
  164. currentGrabber.hitDistance = Mathf.Max(0f, currentGrabber.hitDistance + scrollDelta.y);
  165. }
  166. }
  167. public virtual void OnDrag(PointerEventData eventData) { }
  168. public virtual void OnEndDrag(PointerEventData eventData)
  169. {
  170. if (m_eventGrabberSet == null) { return; }
  171. Grabber grabber;
  172. if (!m_eventGrabberSet.TryGetValue(eventData, out grabber)) { return; }
  173. RemoveGrabber(grabber);
  174. m_eventGrabberSet.Remove(eventData);
  175. Grabber.Release(grabber);
  176. }
  177. }