15 [Tooltip(
"A camera mounted on the controller")]
18 [Tooltip(
"The threshold is a square length at which the cursor will begin drag. Lenght is measured in world coordinates.")]
21 public SteamVR_Action_Boolean
uiInteractAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>(
"InteractUI");
24 private bool m_useDebugText =
false;
25 private string[] m_debugStrings =
new string[5];
28 private bool m_isButtonPressed =
false;
29 private bool m_isButtonPressedChanged =
false;
30 private float m_pressedDistance;
32 private Vector2 m_cameraCenter;
33 private Vector3 m_lastRaycastHitPoint;
34 private PointerEventData m_pointerEventData;
35 private bool m_isActive =
false;
36 private bool IsLeft =
false;
39 public GestureType selectGesture = GestureType.Like;
48 m_cameraCenter =
new Vector2(
uiCamera.pixelWidth / 2,
uiCamera.pixelHeight / 2);
51 WriteDebug(
"Camera center: " + m_cameraCenter.ToString());
59 bool usedEvent = SendUpdateEventToSelectedObject();
61 MyUpdateControllerData();
62 ProcessControllerEvent();
66 private void MyUpdateControllerData()
68 m_isButtonPressedChanged =
false;
69 if (m_isButtonPressed != VRInputManager.GetIsControllerButtonPressed())
71 m_isButtonPressedChanged =
true;
72 m_isButtonPressed = VRInputManager.GetIsControllerButtonPressed();
76 private void ProcessControllerEvent()
78 PointerEventData eventData = GetPointerEventData();
80 ProcessPress(eventData);
81 ProcessMove(eventData);
82 ProcessDrag(eventData);
85 private PointerEventData GetPointerEventData()
89 if (
null == m_pointerEventData)
90 m_pointerEventData =
new PointerEventData(eventSystem);
92 if (VRInputManager.GetControllerActive())
94 m_pointerEventData.position = m_cameraCenter;
96 m_pointerEventData.scrollDelta =
Vector2.zero;
97 m_pointerEventData.button = PointerEventData.InputButton.Left;
98 eventSystem.RaycastAll(m_pointerEventData, m_RaycastResultCache);
99 var raycast = FindFirstRaycast(m_RaycastResultCache);
105 Vector3 hitPoint = ray.GetPoint(raycast.distance);
106 m_pointerEventData.delta =
new Vector2((hitPoint - m_lastRaycastHitPoint).sqrMagnitude, 0);
107 m_lastRaycastHitPoint = hitPoint;
109 m_pointerEventData.pointerCurrentRaycast = raycast;
112 if (m_RaycastResultCache.Count > 0)
113 WriteDebug(
"Raycast hit " + raycast.gameObject.name);
115 if (raycast.isValid && raycast.gameObject.gameObject && raycast.gameObject.GetComponent<
PointerInteractable>())
118 GestureResult result = IsLeft ? GestureProvider.LeftHand : GestureProvider.RightHand;
119 if (result.gesture == selectGesture)
136 m_RaycastResultCache.Clear();
139 return m_pointerEventData;
143 private void ProcessDrag(PointerEventData eventData)
145 WriteDebug(eventData.delta.sqrMagnitude.ToString());
148 if (!eventData.IsPointerMoving() || eventData.pointerDrag ==
null)
152 if (!eventData.dragging)
154 m_pressedDistance += eventData.delta.x;
156 if (ShouldStartDrag(eventData))
158 ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.beginDragHandler);
159 eventData.dragging =
true;
164 if (eventData.dragging)
168 if (eventData.pointerPress != eventData.pointerDrag)
170 ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.pointerUpHandler);
172 eventData.eligibleForClick =
false;
173 eventData.pointerPress =
null;
174 eventData.rawPointerPress =
null;
176 ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.dragHandler);
180 private bool ShouldStartDrag(PointerEventData eventData)
182 return !m_isButtonPressedChanged && (m_pressedDistance >
dragThreshold);
186 private void ProcessMove(PointerEventData eventData)
188 var targetGO = eventData.pointerCurrentRaycast.gameObject;
189 HandlePointerExitAndEnter(eventData, targetGO);
193 private void ProcessPress(PointerEventData eventData)
195 var currentOverGo = eventData.pointerCurrentRaycast.gameObject;
198 if (MyIsButtonPressedThisFrame())
200 eventData.eligibleForClick =
true;
201 eventData.delta =
Vector2.zero;
202 eventData.useDragThreshold =
true;
203 eventData.pressPosition = eventData.position;
204 eventData.pointerPressRaycast = eventData.pointerCurrentRaycast;
206 DeselectIfSelectionChanged(currentOverGo, eventData);
208 var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, eventData, ExecuteEvents.pointerDownHandler);
211 if (newPressed ==
null)
212 newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
214 eventData.pointerPress = newPressed;
215 m_pressedDistance = 0;
216 eventData.rawPointerPress = currentOverGo;
218 eventData.clickTime = Time.unscaledTime;
221 eventData.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo);
223 if (eventData.pointerDrag !=
null)
224 ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.initializePotentialDrag);
228 if (MyIsButtonReleasedThisFrame())
230 ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.pointerUpHandler);
233 var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
236 if (eventData.pointerPress == pointerUpHandler && eventData.eligibleForClick)
238 ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.pointerClickHandler);
240 else if (eventData.pointerDrag !=
null && eventData.dragging)
242 ExecuteEvents.ExecuteHierarchy(currentOverGo, eventData, ExecuteEvents.dropHandler);
245 eventData.eligibleForClick =
false;
246 eventData.pointerPress =
null;
247 m_pressedDistance = 0;
248 eventData.rawPointerPress =
null;
250 if (eventData.pointerDrag !=
null && eventData.dragging)
251 ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.endDragHandler);
253 eventData.dragging =
false;
254 eventData.pointerDrag =
null;
260 if (currentOverGo != eventData.pointerEnter)
262 HandlePointerExitAndEnter(eventData,
null);
263 HandlePointerExitAndEnter(eventData, currentOverGo);
269 private void DeselectIfSelectionChanged(GameObject currentOverGo, BaseEventData pointerEvent)
272 var selectHandlerGO = ExecuteEvents.GetEventHandler<ISelectHandler>(currentOverGo);
275 if (selectHandlerGO != eventSystem.currentSelectedGameObject)
276 eventSystem.SetSelectedGameObject(
null, pointerEvent);
280 private bool SendUpdateEventToSelectedObject()
282 if (eventSystem.currentSelectedGameObject ==
null)
285 var data = GetBaseEventData();
286 ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler);
290 private bool MyIsButtonReleasedThisFrame()
292 return (m_isButtonPressedChanged && !m_isButtonPressed);
295 private bool MyIsButtonPressedThisFrame()
297 return (m_isButtonPressedChanged && m_isButtonPressed);
301 private void WriteDebug(
string text)
306 m_debugStrings[4] = m_debugStrings[3];
307 m_debugStrings[3] = m_debugStrings[2];
308 m_debugStrings[2] = m_debugStrings[1];
309 m_debugStrings[1] = m_debugStrings[0];
310 m_debugStrings[0] = text;
311 uiDebugText.text =
string.Format(
"{0}\n{1}\n{2}\n{3}\n{4}", m_debugStrings[0], m_debugStrings[1], m_debugStrings[2], m_debugStrings[3], m_debugStrings[4]);