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.
651 lines
24 KiB
651 lines
24 KiB
3 years ago
|
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. ===========
|
||
|
|
||
|
using HTC.UnityPlugin.Utility;
|
||
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.EventSystems;
|
||
|
|
||
|
namespace HTC.UnityPlugin.Pointer3D
|
||
|
{
|
||
|
public class Pointer3DInputModule : BaseInputModule
|
||
|
{
|
||
|
private static Pointer3DInputModule instance;
|
||
|
private static bool isApplicationQuitting = false;
|
||
|
|
||
|
private static readonly IndexedSet<Pointer3DRaycaster> raycasters = new IndexedSet<Pointer3DRaycaster>();
|
||
|
private static IndexedSet<Pointer3DRaycaster> processingRaycasters = new IndexedSet<Pointer3DRaycaster>();
|
||
|
private static int validEventDataId = PointerInputModule.kFakeTouchesId - 1;
|
||
|
|
||
|
#if UNITY_5_5_OR_NEWER
|
||
|
private bool m_hasFocus;
|
||
|
#endif
|
||
|
private int m_processedFrame;
|
||
|
|
||
|
// Pointer3DInputModule has it's own RaycasterManager and Pointer3DRaycaster doesn't share with other input modules.
|
||
|
// So coexist with other input modules is by default and reasonable?
|
||
|
public bool coexist = true;
|
||
|
[NonSerialized]
|
||
|
[Obsolete("Use Pointer3DRaycaster.dragThreshold instead")]
|
||
|
public float dragThreshold = 0.02f;
|
||
|
[NonSerialized]
|
||
|
[Obsolete("Use Pointer3DRaycaster.clickInterval instead")]
|
||
|
public float clickInterval = 0.3f;
|
||
|
|
||
|
public static Vector2 ScreenCenterPoint { get { return new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); } }
|
||
|
|
||
|
public static bool Active { get { return instance != null; } }
|
||
|
|
||
|
public static Pointer3DInputModule Instance
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
Initialize();
|
||
|
return instance;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected virtual void OnApplicationQuit()
|
||
|
{
|
||
|
isApplicationQuitting = true;
|
||
|
}
|
||
|
|
||
|
public override bool ShouldActivateModule()
|
||
|
{
|
||
|
if (!base.ShouldActivateModule()) { return false; }
|
||
|
// if coexist with other inputmodule is enabled, tell EventSystem not to active and let other module active first
|
||
|
return !coexist;
|
||
|
}
|
||
|
#if UNITY_5_5_OR_NEWER
|
||
|
protected virtual void OnApplicationFocus(bool hasFocus)
|
||
|
{
|
||
|
m_hasFocus = hasFocus;
|
||
|
}
|
||
|
|
||
|
protected virtual void Update()
|
||
|
{
|
||
|
// EventSystem is paused when application lost focus, so force ProcessRaycast here
|
||
|
if (isActiveAndEnabled && !m_hasFocus)
|
||
|
{
|
||
|
if (EventSystem.current.currentInputModule == this || coexist)
|
||
|
{
|
||
|
ProcessRaycast();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
public override void UpdateModule()
|
||
|
{
|
||
|
Initialize();
|
||
|
if (isActiveAndEnabled && EventSystem.current.currentInputModule != this && coexist)
|
||
|
{
|
||
|
ProcessRaycast();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void Initialize()
|
||
|
{
|
||
|
if (Active || isApplicationQuitting) { return; }
|
||
|
|
||
|
var instances = FindObjectsOfType<Pointer3DInputModule>();
|
||
|
if (instances.Length > 0)
|
||
|
{
|
||
|
instance = instances[0];
|
||
|
if (instances.Length > 1) { Debug.LogWarning("Multiple Pointer3DInputModule not supported!"); }
|
||
|
}
|
||
|
|
||
|
if (!Active)
|
||
|
{
|
||
|
EventSystem eventSystem = EventSystem.current;
|
||
|
if (eventSystem == null)
|
||
|
{
|
||
|
eventSystem = FindObjectOfType<EventSystem>();
|
||
|
}
|
||
|
if (eventSystem == null)
|
||
|
{
|
||
|
eventSystem = new GameObject("[EventSystem]").AddComponent<EventSystem>();
|
||
|
}
|
||
|
if (eventSystem == null)
|
||
|
{
|
||
|
Debug.LogWarning("EventSystem not found or create fail!");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
instance = eventSystem.gameObject.AddComponent<Pointer3DInputModule>();
|
||
|
}
|
||
|
|
||
|
if (Active)
|
||
|
{
|
||
|
DontDestroyOnLoad(instance.gameObject);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void AssignPointerId(Pointer3DEventData eventData)
|
||
|
{
|
||
|
eventData.pointerId = validEventDataId--;
|
||
|
}
|
||
|
|
||
|
public override void Process()
|
||
|
{
|
||
|
Initialize();
|
||
|
if (isActiveAndEnabled)
|
||
|
{
|
||
|
ProcessRaycast();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void OnDisable()
|
||
|
{
|
||
|
base.OnDisable();
|
||
|
|
||
|
if (Active && processingRaycasters.Count == 0)
|
||
|
{
|
||
|
for (var i = raycasters.Count - 1; i >= 0; --i)
|
||
|
{
|
||
|
instance.CleanUpRaycaster(raycasters[i]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static readonly Comparison<RaycastResult> defaultRaycastComparer = RaycastComparer;
|
||
|
private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs)
|
||
|
{
|
||
|
if (lhs.module != rhs.module)
|
||
|
{
|
||
|
if (lhs.module.eventCamera != null && rhs.module.eventCamera != null && lhs.module.eventCamera.depth != rhs.module.eventCamera.depth)
|
||
|
{
|
||
|
// need to reverse the standard compareTo
|
||
|
if (lhs.module.eventCamera.depth < rhs.module.eventCamera.depth) { return 1; }
|
||
|
if (lhs.module.eventCamera.depth == rhs.module.eventCamera.depth) { return 0; }
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (lhs.module.sortOrderPriority != rhs.module.sortOrderPriority)
|
||
|
{
|
||
|
return rhs.module.sortOrderPriority.CompareTo(lhs.module.sortOrderPriority);
|
||
|
}
|
||
|
|
||
|
if (lhs.module.renderOrderPriority != rhs.module.renderOrderPriority)
|
||
|
{
|
||
|
return rhs.module.renderOrderPriority.CompareTo(lhs.module.renderOrderPriority);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (lhs.sortingLayer != rhs.sortingLayer)
|
||
|
{
|
||
|
// Uses the layer value to properly compare the relative order of the layers.
|
||
|
var rid = SortingLayer.GetLayerValueFromID(rhs.sortingLayer);
|
||
|
var lid = SortingLayer.GetLayerValueFromID(lhs.sortingLayer);
|
||
|
return rid.CompareTo(lid);
|
||
|
}
|
||
|
|
||
|
if (lhs.sortingOrder != rhs.sortingOrder)
|
||
|
{
|
||
|
return rhs.sortingOrder.CompareTo(lhs.sortingOrder);
|
||
|
}
|
||
|
|
||
|
if (!Mathf.Approximately(lhs.distance, rhs.distance))
|
||
|
{
|
||
|
return lhs.distance.CompareTo(rhs.distance);
|
||
|
}
|
||
|
|
||
|
if (lhs.depth != rhs.depth)
|
||
|
{
|
||
|
return rhs.depth.CompareTo(lhs.depth);
|
||
|
}
|
||
|
|
||
|
return lhs.index.CompareTo(rhs.index);
|
||
|
}
|
||
|
|
||
|
public static void AddRaycaster(Pointer3DRaycaster raycaster)
|
||
|
{
|
||
|
if (raycaster == null) { return; }
|
||
|
|
||
|
Initialize();
|
||
|
raycasters.AddUnique(raycaster);
|
||
|
}
|
||
|
|
||
|
public static void RemoveRaycaster(Pointer3DRaycaster raycaster)
|
||
|
{
|
||
|
if (!raycasters.Remove(raycaster)) { return; }
|
||
|
|
||
|
if (!processingRaycasters.Contains(raycaster) && Active)
|
||
|
{
|
||
|
Instance.CleanUpRaycaster(raycaster);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Obsolete("Use RemoveRaycaster instead")]
|
||
|
public static void RemoveRaycasters(Pointer3DRaycaster raycaster) { RemoveRaycaster(raycaster); }
|
||
|
|
||
|
protected void CleanUpRaycaster(Pointer3DRaycaster raycaster)
|
||
|
{
|
||
|
if (raycaster == null) { return; }
|
||
|
|
||
|
var hoverEventData = raycaster.HoverEventData;
|
||
|
|
||
|
// buttons event
|
||
|
for (int i = 0, imax = raycaster.ButtonEventDataList.Count; i < imax; ++i)
|
||
|
{
|
||
|
var buttonEventData = raycaster.ButtonEventDataList[i];
|
||
|
if (buttonEventData == null) { continue; }
|
||
|
|
||
|
buttonEventData.Reset();
|
||
|
|
||
|
if (buttonEventData.pressPrecessed)
|
||
|
{
|
||
|
ProcessPressUp(buttonEventData);
|
||
|
HandlePressExitAndEnter(buttonEventData, null);
|
||
|
}
|
||
|
|
||
|
if (buttonEventData.pointerEnter != null)
|
||
|
{
|
||
|
if (buttonEventData == hoverEventData)
|
||
|
{
|
||
|
// perform exit event only for hover event data
|
||
|
HandlePointerExitAndEnter(buttonEventData, null);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
buttonEventData.pointerEnter = null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
raycaster.CleanUpRaycast();
|
||
|
|
||
|
for (int i = 0, imax = raycaster.ButtonEventDataList.Count; i < imax; ++i)
|
||
|
{
|
||
|
raycaster.ButtonEventDataList[i].pointerPressRaycast = default(RaycastResult);
|
||
|
raycaster.ButtonEventDataList[i].pointerCurrentRaycast = default(RaycastResult);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected virtual void ProcessRaycast()
|
||
|
{
|
||
|
if (m_processedFrame == Time.frameCount) { return; }
|
||
|
m_processedFrame = Time.frameCount;
|
||
|
|
||
|
// use another list to iterate raycasters
|
||
|
// incase that raycasters may changed during this process cycle
|
||
|
for (int i = 0, imax = raycasters.Count; i < imax; ++i)
|
||
|
{
|
||
|
var r = raycasters[i];
|
||
|
|
||
|
if (r != null)
|
||
|
{
|
||
|
processingRaycasters.Add(r);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (var i = processingRaycasters.Count - 1; i >= 0; --i)
|
||
|
{
|
||
|
var raycaster = processingRaycasters[i];
|
||
|
if (raycaster == null) { continue; }
|
||
|
|
||
|
raycaster.Raycast();
|
||
|
var result = raycaster.FirstRaycastResult();
|
||
|
|
||
|
// prepare raycaster value
|
||
|
var scrollDelta = raycaster.GetScrollDelta();
|
||
|
var raycasterPos = raycaster.transform.position;
|
||
|
var raycasterRot = raycaster.transform.rotation;
|
||
|
|
||
|
var hoverEventData = raycaster.HoverEventData;
|
||
|
if (hoverEventData == null) { continue; }
|
||
|
|
||
|
// gen shared data and put in hover event
|
||
|
hoverEventData.Reset();
|
||
|
hoverEventData.delta = Vector2.zero;
|
||
|
hoverEventData.scrollDelta = scrollDelta;
|
||
|
hoverEventData.position = ScreenCenterPoint;
|
||
|
hoverEventData.pointerCurrentRaycast = result;
|
||
|
|
||
|
hoverEventData.position3DDelta = raycasterPos - hoverEventData.position3D;
|
||
|
hoverEventData.position3D = raycasterPos;
|
||
|
hoverEventData.rotationDelta = Quaternion.Inverse(hoverEventData.rotation) * raycasterRot;
|
||
|
hoverEventData.rotation = raycasterRot;
|
||
|
|
||
|
// copy data to other button event
|
||
|
for (int j = 0, jmax = raycaster.ButtonEventDataList.Count; j < jmax; ++j)
|
||
|
{
|
||
|
var buttonEventData = raycaster.ButtonEventDataList[j];
|
||
|
if (buttonEventData == null || buttonEventData == hoverEventData) { continue; }
|
||
|
|
||
|
buttonEventData.Reset();
|
||
|
buttonEventData.delta = Vector2.zero;
|
||
|
buttonEventData.scrollDelta = scrollDelta;
|
||
|
buttonEventData.position = ScreenCenterPoint;
|
||
|
buttonEventData.pointerCurrentRaycast = result;
|
||
|
|
||
|
buttonEventData.position3DDelta = hoverEventData.position3DDelta;
|
||
|
buttonEventData.position3D = hoverEventData.position3D;
|
||
|
buttonEventData.rotationDelta = hoverEventData.rotationDelta;
|
||
|
buttonEventData.rotation = hoverEventData.rotation;
|
||
|
}
|
||
|
|
||
|
ProcessPress(hoverEventData);
|
||
|
ProcessMove(hoverEventData);
|
||
|
ProcessDrag(hoverEventData);
|
||
|
|
||
|
// other buttons event
|
||
|
for (int j = 1, jmax = raycaster.ButtonEventDataList.Count; j < jmax; ++j)
|
||
|
{
|
||
|
var buttonEventData = raycaster.ButtonEventDataList[j];
|
||
|
if (buttonEventData == null || buttonEventData == hoverEventData) { continue; }
|
||
|
|
||
|
buttonEventData.pointerEnter = hoverEventData.pointerEnter;
|
||
|
|
||
|
ProcessPress(buttonEventData);
|
||
|
ProcessDrag(buttonEventData);
|
||
|
}
|
||
|
|
||
|
// scroll event
|
||
|
if (result.isValid && !Mathf.Approximately(scrollDelta.sqrMagnitude, 0.0f))
|
||
|
{
|
||
|
var scrollHandler = ExecuteEvents.GetEventHandler<IScrollHandler>(result.gameObject);
|
||
|
ExecuteEvents.ExecuteHierarchy(scrollHandler, hoverEventData, ExecuteEvents.scrollHandler);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (isActiveAndEnabled)
|
||
|
{
|
||
|
for (var i = processingRaycasters.Count - 1; i >= 0; --i)
|
||
|
{
|
||
|
var r = processingRaycasters[i];
|
||
|
if (!raycasters.Contains(r))
|
||
|
{
|
||
|
CleanUpRaycaster(r);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (var i = processingRaycasters.Count - 1; i >= 0; --i)
|
||
|
{
|
||
|
CleanUpRaycaster(processingRaycasters[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
processingRaycasters.Clear();
|
||
|
}
|
||
|
|
||
|
protected virtual void ProcessMove(PointerEventData eventData)
|
||
|
{
|
||
|
var hoverGO = eventData.pointerCurrentRaycast.gameObject;
|
||
|
if (eventData.pointerEnter != hoverGO)
|
||
|
{
|
||
|
HandlePointerExitAndEnter(eventData, hoverGO);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected virtual void ProcessPress(Pointer3DEventData eventData)
|
||
|
{
|
||
|
if (eventData.GetPress())
|
||
|
{
|
||
|
if (!eventData.pressPrecessed)
|
||
|
{
|
||
|
ProcessPressDown(eventData);
|
||
|
}
|
||
|
|
||
|
HandlePressExitAndEnter(eventData, eventData.pointerCurrentRaycast.gameObject);
|
||
|
}
|
||
|
else if (eventData.pressPrecessed)
|
||
|
{
|
||
|
ProcessPressUp(eventData);
|
||
|
HandlePressExitAndEnter(eventData, null);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected void ProcessPressDown(Pointer3DEventData eventData)
|
||
|
{
|
||
|
var currentOverGo = eventData.pointerCurrentRaycast.gameObject;
|
||
|
|
||
|
eventData.pressPrecessed = true;
|
||
|
eventData.eligibleForClick = true;
|
||
|
eventData.delta = Vector2.zero;
|
||
|
eventData.dragging = false;
|
||
|
eventData.useDragThreshold = true;
|
||
|
eventData.pressPosition = eventData.position;
|
||
|
eventData.pressPosition3D = eventData.position3D;
|
||
|
eventData.pressRotation = eventData.rotation;
|
||
|
eventData.pressDistance = eventData.pointerCurrentRaycast.distance;
|
||
|
eventData.pointerPressRaycast = eventData.pointerCurrentRaycast;
|
||
|
|
||
|
DeselectIfSelectionChanged(currentOverGo, eventData);
|
||
|
|
||
|
// search for the control that will receive the press
|
||
|
// if we can't find a press handler set the press
|
||
|
// handler to be what would receive a click.
|
||
|
var newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, eventData, ExecuteEvents.pointerDownHandler);
|
||
|
|
||
|
// didnt find a press handler... search for a click handler
|
||
|
if (newPressed == null)
|
||
|
{
|
||
|
newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
|
||
|
}
|
||
|
|
||
|
var time = Time.unscaledTime;
|
||
|
|
||
|
if (newPressed == eventData.lastPress)
|
||
|
{
|
||
|
if (eventData.raycaster != null && time < (eventData.clickTime + eventData.raycaster.clickInterval))
|
||
|
{
|
||
|
++eventData.clickCount;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
eventData.clickCount = 1;
|
||
|
}
|
||
|
|
||
|
eventData.clickTime = time;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
eventData.clickCount = 1;
|
||
|
}
|
||
|
|
||
|
eventData.pointerPress = newPressed;
|
||
|
eventData.rawPointerPress = currentOverGo;
|
||
|
|
||
|
eventData.clickTime = time;
|
||
|
|
||
|
// Save the drag handler as well
|
||
|
eventData.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo);
|
||
|
|
||
|
if (eventData.pointerDrag != null)
|
||
|
{
|
||
|
ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.initializePotentialDrag);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected void ProcessPressUp(Pointer3DEventData eventData)
|
||
|
{
|
||
|
var currentOverGo = eventData.pointerCurrentRaycast.gameObject;
|
||
|
|
||
|
ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.pointerUpHandler);
|
||
|
|
||
|
// see if we mouse up on the same element that we clicked on...
|
||
|
var pointerUpHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
|
||
|
|
||
|
// PointerClick and Drop events
|
||
|
if (eventData.pointerPress == pointerUpHandler && eventData.eligibleForClick)
|
||
|
{
|
||
|
ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.pointerClickHandler);
|
||
|
}
|
||
|
else if (eventData.pointerDrag != null && eventData.dragging)
|
||
|
{
|
||
|
ExecuteEvents.ExecuteHierarchy(currentOverGo, eventData, ExecuteEvents.dropHandler);
|
||
|
}
|
||
|
|
||
|
eventData.pressPrecessed = false;
|
||
|
eventData.eligibleForClick = false;
|
||
|
eventData.pointerPress = null;
|
||
|
eventData.rawPointerPress = null;
|
||
|
|
||
|
if (eventData.pointerDrag != null && eventData.dragging)
|
||
|
{
|
||
|
ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.endDragHandler);
|
||
|
}
|
||
|
|
||
|
eventData.dragging = false;
|
||
|
eventData.pointerDrag = null;
|
||
|
|
||
|
// redo pointer enter / exit to refresh state
|
||
|
// so that if we moused over something that ignored it before
|
||
|
// due to having pressed on something else
|
||
|
// it now gets it.
|
||
|
if (currentOverGo != eventData.pointerEnter)
|
||
|
{
|
||
|
HandlePointerExitAndEnter(eventData, null);
|
||
|
HandlePointerExitAndEnter(eventData, currentOverGo);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected bool ShouldStartDrag(Pointer3DEventData eventData)
|
||
|
{
|
||
|
if (!eventData.useDragThreshold || eventData.raycaster == null) { return true; }
|
||
|
var currentPos = eventData.position3D + (eventData.rotation * Vector3.forward) * eventData.pressDistance;
|
||
|
var pressPos = eventData.pressPosition3D + (eventData.pressRotation * Vector3.forward) * eventData.pressDistance;
|
||
|
var threshold = eventData.raycaster.dragThreshold;
|
||
|
return (currentPos - pressPos).sqrMagnitude >= threshold * threshold;
|
||
|
}
|
||
|
|
||
|
protected void ProcessDrag(Pointer3DEventData eventData)
|
||
|
{
|
||
|
var moving = !Mathf.Approximately(eventData.position3DDelta.sqrMagnitude, 0f) || !Mathf.Approximately(Quaternion.Angle(Quaternion.identity, eventData.rotationDelta), 0f);
|
||
|
|
||
|
if (moving && eventData.pointerDrag != null && !eventData.dragging && ShouldStartDrag(eventData))
|
||
|
{
|
||
|
ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.beginDragHandler);
|
||
|
eventData.dragging = true;
|
||
|
}
|
||
|
|
||
|
// Drag notification
|
||
|
if (eventData.dragging && moving && eventData.pointerDrag != null)
|
||
|
{
|
||
|
// Before doing drag we should cancel any pointer down state
|
||
|
// And clear selection!
|
||
|
if (eventData.pointerPress != eventData.pointerDrag)
|
||
|
{
|
||
|
ExecuteEvents.Execute(eventData.pointerPress, eventData, ExecuteEvents.pointerUpHandler);
|
||
|
|
||
|
eventData.eligibleForClick = false;
|
||
|
eventData.pointerPress = null;
|
||
|
eventData.rawPointerPress = null;
|
||
|
}
|
||
|
ExecuteEvents.Execute(eventData.pointerDrag, eventData, ExecuteEvents.dragHandler);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected static void HandlePressExitAndEnter(Pointer3DEventData eventData, GameObject newEnterTarget)
|
||
|
{
|
||
|
if (eventData.pressEnter == newEnterTarget) { return; }
|
||
|
|
||
|
var oldTarget = eventData.pressEnter == null ? null : eventData.pressEnter.transform;
|
||
|
var newTarget = newEnterTarget == null ? null : newEnterTarget.transform;
|
||
|
var commonRoot = default(Transform);
|
||
|
|
||
|
for (var t = oldTarget; t != null; t = t.parent)
|
||
|
{
|
||
|
if (newTarget != null && newTarget.IsChildOf(t))
|
||
|
{
|
||
|
commonRoot = t;
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ExecuteEvents.Execute(t.gameObject, eventData, ExecutePointer3DEvents.PressExitHandler);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
eventData.pressEnter = newEnterTarget;
|
||
|
|
||
|
for (var t = newTarget; t != commonRoot; t = t.parent)
|
||
|
{
|
||
|
ExecuteEvents.Execute(t.gameObject, eventData, ExecutePointer3DEvents.PressEnterHandler);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected void DeselectIfSelectionChanged(GameObject currentOverGo, BaseEventData pointerEvent)
|
||
|
{
|
||
|
// Selection tracking
|
||
|
var selectHandlerGO = ExecuteEvents.GetEventHandler<ISelectHandler>(currentOverGo);
|
||
|
// if we have clicked something new, deselect the old thing
|
||
|
// leave 'selection handling' up to the press event though.
|
||
|
if (eventSystem != null && selectHandlerGO != eventSystem.currentSelectedGameObject)
|
||
|
{
|
||
|
eventSystem.SetSelectedGameObject(null, pointerEvent);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool SendUpdateEventToSelectedObject()
|
||
|
{
|
||
|
var selected = EventSystem.current.currentSelectedGameObject;
|
||
|
if (selected == null) { return false; }
|
||
|
|
||
|
var data = GetBaseEventData();
|
||
|
ExecuteEvents.Execute(selected, data, ExecuteEvents.updateSelectedHandler);
|
||
|
return data.used;
|
||
|
}
|
||
|
|
||
|
public bool SendSubmitEventToSelectedObject(bool submit, bool cencel)
|
||
|
{
|
||
|
var selected = EventSystem.current.currentSelectedGameObject;
|
||
|
if (selected == null) { return false; }
|
||
|
|
||
|
var data = GetBaseEventData();
|
||
|
if (submit) { ExecuteEvents.Execute(selected, data, ExecuteEvents.submitHandler); }
|
||
|
if (cencel) { ExecuteEvents.Execute(selected, data, ExecuteEvents.cancelHandler); }
|
||
|
return data.used;
|
||
|
}
|
||
|
|
||
|
public bool SendMoveEventToSelectedObject(float x, float y, float moveDeadZone)
|
||
|
{
|
||
|
var selected = EventSystem.current.currentSelectedGameObject;
|
||
|
if (selected == null) { return false; }
|
||
|
|
||
|
var data = GetAxisEventData(x, y, moveDeadZone);
|
||
|
ExecuteEvents.Execute(selected, data, ExecuteEvents.moveHandler);
|
||
|
return data.used;
|
||
|
}
|
||
|
|
||
|
public static string PrintGOPath(GameObject go)
|
||
|
{
|
||
|
var str = string.Empty;
|
||
|
|
||
|
if (go != null)
|
||
|
{
|
||
|
for (var t = go.transform; t != null; t = t.parent)
|
||
|
{
|
||
|
if (!string.IsNullOrEmpty(str)) { str = "." + str; }
|
||
|
str = t.name + str;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
public override string ToString()
|
||
|
{
|
||
|
var str = string.Empty;
|
||
|
if (raycasters.Count == 0)
|
||
|
{
|
||
|
str += "No raycaster registered";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (int i = 0, imax = raycasters.Count; i < imax; ++i)
|
||
|
{
|
||
|
var raycaster = raycasters[i];
|
||
|
if (raycaster == null) { continue; }
|
||
|
|
||
|
str += "<b>Raycaster: [" + i + "]</b>\n";
|
||
|
str += raycaster.ToString() + "\n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return str;
|
||
|
}
|
||
|
}
|
||
|
}
|