2 using UnityEngine.EventSystems;
4 using System.Collections.Generic;
13 private GameObject activeGameObject = null;
14 private GameObject previousActiveGameObject = null;
16 private LineRenderer lineRenderer;
25 private LayerMask layerMask;
27 private Vector2 lastTextureCoord;
28 private Vector3 lastHitWorldPos;
30 private Vector2 fakeUIScreenPosition;
32 private RaycastHit raycastHit;
33 private RaycastResult raycastResult;
35 private bool isPointerOverUI =
false;
36 private bool isPointerOverPlatformUI =
false;
38 protected override void Start()
40 lineRenderer = this.GetComponent<LineRenderer>();
52 public void resetLayerMask() {
59 public void disableLayer(
string layer) {
61 int l = LayerMask.NameToLayer (layer);
62 layerMask.value &= ~(1 << l);
65 public void enableLayer(
string layer) {
67 int l = LayerMask.NameToLayer (layer);
68 layerMask.value |= (1 << l);
74 previousActiveGameObject = activeGameObject;
75 activeGameObject = null;
77 Vector2 hitTextureCoord = Vector2.zero;
78 int hitTriangleIndex = -1;
79 Vector3 hitWorldPos = Vector3.zero;
81 isPointerOverUI =
false;
82 isPointerOverPlatformUI =
false;
85 if( idm.currentInputDevice != null )
88 Ray ray = idm.currentInputDevice.createRay ();
89 lineRenderer.SetPosition (0, ray.origin);
93 int layerMaskLocal = ~(1 << LayerMask.NameToLayer (
"UI"));
95 layerMaskLocal &= layerMask.value;
96 if (Physics.Raycast (ray, out raycastHit, Mathf.Infinity, layerMaskLocal)) {
98 activeGameObject = raycastHit.transform.gameObject;
99 hitTextureCoord = raycastHit.textureCoord;
100 hitWorldPos = raycastHit.point;
101 hitTriangleIndex = raycastHit.triangleIndex;
103 lineRenderer.SetPosition (1, raycastHit.point);
106 if (raycastHit.transform.gameObject ==
Platform.instance.UIMesh) {
108 if (UIRaycast (raycastHit.textureCoord, out raycastResult)) {
109 activeGameObject = raycastResult.gameObject;
110 lineRenderer.SetPosition (1, raycastHit.point);
111 hitWorldPos = raycastResult.worldPosition;
112 isPointerOverUI =
true;
113 isPointerOverPlatformUI =
true;
115 RectTransform rt = activeGameObject.GetComponent<RectTransform> ();
116 RectTransformUtility.ScreenPointToLocalPointInRectangle ( rt,
117 raycastResult.screenPosition, UI.Core.instance.UICamera, out localPoint);
119 hitTextureCoord =
new Vector2 ((localPoint.x - rt.rect.min.x) / rt.rect.width,
120 (localPoint.y - rt.rect.min.y) / rt.rect.height);
121 hitTriangleIndex = raycastHit.triangleIndex;
125 layerMaskLocal = ~(1 << LayerMask.NameToLayer (
"UIMesh"));
126 layerMaskLocal &= layerMask.value;
127 if (Physics.Raycast (ray, out raycastHit, Mathf.Infinity, layerMaskLocal)) {
128 activeGameObject = raycastHit.transform.gameObject;
129 lineRenderer.SetPosition (1, raycastHit.point);
131 hitTextureCoord = raycastHit.textureCoord;
132 hitTriangleIndex = raycastHit.triangleIndex;
133 hitWorldPos = raycastHit.point;
135 activeGameObject = null;
140 if (raycastHit.transform != null) {
141 if (raycastHit.transform.gameObject.layer == LayerMask.NameToLayer (
"UITool") ||
142 raycastHit.transform.gameObject.layer == LayerMask.NameToLayer (
"UIOrgans") ||
143 raycastHit.transform.gameObject.layer == LayerMask.NameToLayer (
"UIAnnotationEdit") ) {
145 RectTransform tf = raycastHit.transform.GetComponent<RectTransform> ();
146 PointerEventData data =
new PointerEventData (EventSystem.current);
147 data.position =
new Vector2 (tf.InverseTransformPoint (raycastHit.point).x, tf.InverseTransformPoint (raycastHit.point).y);
148 List<RaycastResult> raycastResults =
new List<RaycastResult> ();
149 raycastHit.transform.GetComponent<
CanvasRaycaster> ().Raycast (data, raycastResults);
150 if (raycastResults.Count > 0) {
151 raycastResult = raycastResults [0];
152 activeGameObject = raycastResult.gameObject;
153 lineRenderer.SetPosition (1, raycastHit.point);
154 hitWorldPos = raycastResult.worldPosition;
155 data.pointerCurrentRaycast = raycastResult;
156 isPointerOverUI =
true;
157 if (raycastHit.transform.gameObject.layer == LayerMask.NameToLayer (
"UITool")) {
158 isPointerOverPlatformUI =
true;
167 if (activeGameObject != null) {
168 lineRenderer.SetPosition (1, raycastHit.point);
171 lineRenderer.SetPosition (1, ray.origin + ray.direction*300f);
174 if (activeGameObject == previousActiveGameObject) {
175 eventData.delta = hitTextureCoord - lastTextureCoord;
176 eventData.delta3D = hitWorldPos - lastHitWorldPos;
178 eventData.delta = Vector2.zero;
179 eventData.delta3D = Vector3.zero;
181 idm.currentInputDevice.setTexCoordDelta (eventData.delta);
182 idm.currentInputDevice.set3DDelta (eventData.delta3D);
187 lastTextureCoord = hitTextureCoord;
188 lastHitWorldPos = hitWorldPos;
189 eventData.textureCoord = hitTextureCoord;
190 eventData.hitTriangleIndex = hitTriangleIndex;
194 private bool UIRaycast( Vector2 screenPoint, out RaycastResult result )
196 Camera uiCamera = UI.Core.instance.UICamera;
197 fakeUIScreenPosition =
new Vector2 (
198 screenPoint.x * uiCamera.targetTexture.width,
199 screenPoint.y * uiCamera.targetTexture.height);
204 PointerEventData data =
new PointerEventData (EventSystem.current);
205 data.position =
new Vector2 (fakeUIScreenPosition.x, fakeUIScreenPosition.y);
206 List<RaycastResult> raycastResults =
new List<RaycastResult> ();
207 EventSystem.current.RaycastAll( data, raycastResults );
208 if (raycastResults.Count > 0) {
209 int UILayer = LayerMask.NameToLayer (
"UI");
210 foreach (RaycastResult r
in raycastResults) {
211 if( r.gameObject != null && r.gameObject.layer == UILayer) {
217 result =
new RaycastResult ();
224 UI.Core.instance.setPointerIsOnUI (isPointerOverUI);
225 UI.Core.instance.setPointerIsOnPlatformUI (isPointerOverPlatformUI);
227 SendUpdateEventToSelectedObject();
232 ButtonInfo buttonInfo;
233 if (idm.currentInputDevice != null) {
234 buttonInfo = idm.currentInputDevice.updateButtonInfo ();
236 buttonInfo =
new ButtonInfo ();
242 eventData.scrollDelta = idm.currentInputDevice.getScrollDelta();
243 if (
InputDeviceManager.instance.currentInputDevice.getDeviceType () == InputDeviceManager.InputDeviceType.ViveController)
244 eventData.scrollDelta *= 100;
247 raycastResult.worldPosition = raycastHit.point;
248 raycastResult.worldNormal = raycastHit.normal;
249 eventData.pointerCurrentRaycast = raycastResult;
250 eventData.position = raycastResult.screenPosition;
252 HandlePointerExitAndEnter (eventData, activeGameObject);
253 if (activeGameObject != null) {
254 ExecuteEvents.ExecuteHierarchy (activeGameObject, eventData, CustomEvents.pointerHoverHandler);
258 CopyFromTo (eventData, leftData);
259 CopyFromTo (eventData, rightData);
260 CopyFromTo (eventData, middleData);
261 CopyFromTo (eventData, triggerData);
262 leftData.button = PointerEventData.InputButton.Left;
263 rightData.button = PointerEventData.InputButton.Right;
264 middleData.button = PointerEventData.InputButton.Middle;
265 triggerData.button = PointerEventData.InputButton.Left;
277 HandleButton (ButtonType.Left, buttonInfo.buttonStates [ButtonType.Left], leftData,
true);
278 ProcessDrag (leftData);
285 HandleButton (ButtonType.Right, buttonInfo.buttonStates [ButtonType.Right], rightData,
false);
286 ProcessDrag (rightData);
292 HandleButton (ButtonType.Middle, buttonInfo.buttonStates [ButtonType.Middle], middleData,
false);
293 ProcessDrag (middleData);
300 HandleButton (ButtonType.Trigger, buttonInfo.buttonStates [ButtonType.Trigger], triggerData,
true);
301 ProcessDrag (triggerData);
308 if (!Mathf.Approximately(eventData.scrollDelta.sqrMagnitude, 0.0f)) {
312 var scrollHandler = ExecuteEvents.GetEventHandler<IScrollHandler> (activeGameObject);
313 ExecuteEvents.ExecuteHierarchy(scrollHandler, eventData, ExecuteEvents.scrollHandler);
319 private void HandleButton( ButtonType buttonType, PointerEventData.FramePressState buttonState,
CustomEventData eventData,
bool allowDragging )
321 GameObject currentOverGo = activeGameObject;
324 if (buttonState == PointerEventData.FramePressState.Pressed || buttonState == PointerEventData.FramePressState.PressedAndReleased )
326 eventData.eligibleForClick =
true;
327 eventData.delta = Vector2.zero;
328 eventData.dragging =
false;
329 eventData.useDragThreshold =
true;
330 eventData.pressPosition = eventData.position;
331 eventData.pointerPressRaycast = eventData.pointerCurrentRaycast;
333 DeselectIfSelectionChanged(currentOverGo, eventData);
338 var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, eventData, ExecuteEvents.pointerDownHandler);
341 if (newPressed == null)
342 newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
346 float time = Time.unscaledTime;
348 if (newPressed == eventData.lastPress)
350 var diffTime = time - eventData.clickTime;
352 ++eventData.clickCount;
354 eventData.clickCount = 1;
356 eventData.clickTime = time;
360 eventData.clickCount = 1;
363 eventData.pointerPress = newPressed;
364 eventData.rawPointerPress = currentOverGo;
366 eventData.clickTime = time;
369 eventData.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo);
371 if (eventData.pointerDrag != null)
372 ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.initializePotentialDrag);
376 if (buttonState == PointerEventData.FramePressState.Released || buttonState == PointerEventData.FramePressState.PressedAndReleased )
379 ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.pointerUpHandler);
384 var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
387 if (eventData.pointerPress == pointerUpHandler && eventData.eligibleForClick)
389 ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.pointerClickHandler);
391 else if (eventData.pointerDrag != null && eventData.dragging)
393 ExecuteEvents.ExecuteHierarchy(currentOverGo, eventData, ExecuteEvents.dropHandler);
396 eventData.eligibleForClick =
false;
397 eventData.pointerPress = null;
398 eventData.rawPointerPress = null;
400 if (eventData.pointerDrag != null && eventData.dragging)
401 ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.endDragHandler);
403 eventData.dragging =
false;
404 eventData.pointerDrag = null;
410 if (currentOverGo != eventData.pointerEnter)
412 HandlePointerExitAndEnter(eventData, null);
413 HandlePointerExitAndEnter(eventData, currentOverGo);
418 protected virtual void ProcessDrag(PointerEventData pointerEvent)
420 bool moving = pointerEvent.IsPointerMoving();
422 if (moving && pointerEvent.pointerDrag != null
423 && !pointerEvent.dragging
424 && ShouldStartDrag(pointerEvent.pressPosition, pointerEvent.position, eventSystem.pixelDragThreshold, pointerEvent.useDragThreshold))
426 ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.beginDragHandler);
427 pointerEvent.dragging =
true;
431 if (pointerEvent.dragging && moving && pointerEvent.pointerDrag != null)
435 if (pointerEvent.pointerPress != pointerEvent.pointerDrag)
437 ExecuteEvents.Execute(pointerEvent.pointerPress, pointerEvent, ExecuteEvents.pointerUpHandler);
439 pointerEvent.eligibleForClick =
false;
440 pointerEvent.pointerPress = null;
441 pointerEvent.rawPointerPress = null;
443 ExecuteEvents.Execute(pointerEvent.pointerDrag, pointerEvent, ExecuteEvents.dragHandler);
446 private static bool ShouldStartDrag(Vector2 pressPos, Vector2 currentPos,
float threshold,
bool useDragThreshold)
448 if (!useDragThreshold)
451 return (pressPos - currentPos).sqrMagnitude >= threshold * threshold;
454 private bool AnyPressed( ButtonInfo buttonInfo )
456 foreach (KeyValuePair<ButtonType, PointerEventData.FramePressState> entry
in buttonInfo.buttonStates) {
457 if (entry.Value == PointerEventData.FramePressState.Pressed || entry.Value == PointerEventData.FramePressState.PressedAndReleased) {
464 protected bool SendUpdateEventToSelectedObject()
466 if (eventSystem.currentSelectedGameObject == null)
469 var data = GetBaseEventData();
470 ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler);
479 public override void DeactivateModule()
483 public override bool IsPointerOverGameObject(
int pointerId)
486 return (activeGameObject != null);
489 public override bool IsModuleSupported()
495 public override bool ShouldActivateModule()
503 @to.position = @from.position;
504 @to.delta = @from.delta;
505 @to.scrollDelta = @from.scrollDelta;
506 @to.pointerCurrentRaycast = @from.pointerCurrentRaycast;
507 @to.pointerEnter = @from.pointerEnter;
508 @to.textureCoord = @from.textureCoord;
509 @to.hitTriangleIndex = @from.hitTriangleIndex;
512 protected void DeselectIfSelectionChanged(GameObject currentOverGo, BaseEventData pointerEvent)
515 var selectHandlerGO = ExecuteEvents.GetEventHandler<ISelectHandler>(currentOverGo);
518 if (selectHandlerGO != eventSystem.currentSelectedGameObject)
519 eventSystem.SetSelectedGameObject(null, pointerEvent);