using System; using System.Collections.Generic; namespace UnityEngine.EventSystems { [RequireComponent(typeof(EventSystem))] public abstract class BaseInputModule : UIBehaviour { [NonSerialized] protected List m_RaycastResultCache = new List(); private AxisEventData m_AxisEventData; private EventSystem m_EventSystem; private BaseEventData m_BaseEventData; #region 输入系统 // 如果m_InputOverride不为空就用它,否则用默认的m_DefaultInput // 如果要自己实现BaseInput,继承此类并给这个字段赋值 // StandaloneInputModule没有自定义,直接采用的是BaseInput protected BaseInput m_InputOverride; private BaseInput m_DefaultInput; public BaseInput input { get { if (m_InputOverride != null) return m_InputOverride; if (m_DefaultInput == null) { var inputs = GetComponents(); foreach (var baseInput in inputs) { // We dont want to use any classes that derrive from BaseInput for default. if (baseInput != null && baseInput.GetType() == typeof(BaseInput)) { m_DefaultInput = baseInput; break; } } if (m_DefaultInput == null) m_DefaultInput = gameObject.AddComponent(); } return m_DefaultInput; } } #endregion protected EventSystem eventSystem { get { return m_EventSystem; } } protected override void OnEnable() { base.OnEnable(); if(input != null) { } m_EventSystem = GetComponent(); m_EventSystem.UpdateModules(); // 把此input module加入EventSystem } protected override void OnDisable() { m_EventSystem.UpdateModules();// 把此input module移出EventSystem base.OnDisable(); } public abstract void Process(); protected static RaycastResult FindFirstRaycast(List candidates) { for (var i = 0; i < candidates.Count; ++i) { if (candidates[i].gameObject == null) continue; return candidates[i]; } return new RaycastResult(); } protected static MoveDirection DetermineMoveDirection(float x, float y) { return DetermineMoveDirection(x, y, 0.6f); } protected static MoveDirection DetermineMoveDirection(float x, float y, float deadZone) { // if vector is too small... just return if (new Vector2(x, y).sqrMagnitude < deadZone * deadZone) return MoveDirection.None; if (Mathf.Abs(x) > Mathf.Abs(y)) { if (x > 0) return MoveDirection.Right; return MoveDirection.Left; } else { if (y > 0) return MoveDirection.Up; return MoveDirection.Down; } } protected static GameObject FindCommonRoot(GameObject g1, GameObject g2) { if (g1 == null || g2 == null) return null; var t1 = g1.transform; while (t1 != null) { var t2 = g2.transform; while (t2 != null) { if (t1 == t2) return t1.gameObject; t2 = t2.parent; } t1 = t1.parent; } return null; } // walk up the tree till a common root between the last entered and the current entered is foung // send exit events up to (but not inluding) the common root. Then send enter events up to // (but not including the common root). protected void HandlePointerExitAndEnter(PointerEventData currentPointerData, GameObject newEnterTarget) { // if we have no target / pointerEnter has been deleted // just send exit events to anything we are tracking // then exit if (newEnterTarget == null || currentPointerData.pointerEnter == null) { for (var i = 0; i < currentPointerData.hovered.Count; ++i) ExecuteEvents.Execute(currentPointerData.hovered[i], currentPointerData, ExecuteEvents.pointerExitHandler); currentPointerData.hovered.Clear(); if (newEnterTarget == null) { currentPointerData.pointerEnter = newEnterTarget; return; } } // if we have not changed hover target if (currentPointerData.pointerEnter == newEnterTarget && newEnterTarget) return; GameObject commonRoot = FindCommonRoot(currentPointerData.pointerEnter, newEnterTarget); // and we already an entered object from last time if (currentPointerData.pointerEnter != null) { // send exit handler call to all elements in the chain // until we reach the new target, or null! Transform t = currentPointerData.pointerEnter.transform; while (t != null) { // if we reach the common root break out! if (commonRoot != null && commonRoot.transform == t) break; ExecuteEvents.Execute(t.gameObject, currentPointerData, ExecuteEvents.pointerExitHandler); currentPointerData.hovered.Remove(t.gameObject); t = t.parent; } } // now issue the enter call up to but not including the common root currentPointerData.pointerEnter = newEnterTarget; if (newEnterTarget != null) { Transform t = newEnterTarget.transform; while (t != null && t.gameObject != commonRoot) { ExecuteEvents.Execute(t.gameObject, currentPointerData, ExecuteEvents.pointerEnterHandler); currentPointerData.hovered.Add(t.gameObject); t = t.parent; } } } protected virtual AxisEventData GetAxisEventData(float x, float y, float moveDeadZone) { if (m_AxisEventData == null) m_AxisEventData = new AxisEventData(eventSystem); m_AxisEventData.Reset(); m_AxisEventData.moveVector = new Vector2(x, y); m_AxisEventData.moveDir = DetermineMoveDirection(x, y, moveDeadZone); return m_AxisEventData; } protected virtual BaseEventData GetBaseEventData() { if (m_BaseEventData == null) m_BaseEventData = new BaseEventData(eventSystem); m_BaseEventData.Reset(); return m_BaseEventData; } public virtual bool IsPointerOverGameObject(int pointerId) { return false; } public virtual bool ShouldActivateModule() { return enabled && gameObject.activeInHierarchy; } public virtual void DeactivateModule() {} public virtual void ActivateModule() {} public virtual void UpdateModule() {} public virtual bool IsModuleSupported() { return true; } } }