using System; using System.Collections.Generic; using System.Text; using UnityEngine; using UnityEngine.Serialization; namespace UnityEngine.EventSystems { [AddComponentMenu("Event/Event System")] public class EventSystem : UIBehaviour { // 获得当前EventSystem挂着的BaseInputModule的派生类,一般来说只会挂一个StandableInputModule private List m_SystemInputModules = new List(); private BaseInputModule m_CurrentInputModule; public static EventSystem current { get; set; } [SerializeField] [FormerlySerializedAs("m_Selected")] private GameObject m_FirstSelected; [SerializeField] private bool m_sendNavigationEvents = true; // Should the EventSystem allow navigation events (move / submit / cancel). public bool sendNavigationEvents { get { return m_sendNavigationEvents; } set { m_sendNavigationEvents = value; } } [SerializeField] private int m_DragThreshold = 5; public int pixelDragThreshold { get { return m_DragThreshold; } set { m_DragThreshold = value; } } private GameObject m_CurrentSelected; public BaseInputModule currentInputModule { get { return m_CurrentInputModule; } } /// /// Only one object can be selected at a time. Think: controller-selected button. /// public GameObject firstSelectedGameObject { get { return m_FirstSelected; } set { m_FirstSelected = value; } } public GameObject currentSelectedGameObject { get { return m_CurrentSelected; } } [Obsolete("lastSelectedGameObject is no longer supported")] public GameObject lastSelectedGameObject { get { return null; } } private bool m_HasFocus = true; public bool isFocused { get { return m_HasFocus; } } protected EventSystem() {} //c 把挂着的input modules加入m_SystemInputModules public void UpdateModules() { // 拿到当前EventSystem下面挂着的inputmodule,通常来说只会挂一个standaloneInputModule GetComponents(m_SystemInputModules); for (int i = m_SystemInputModules.Count - 1; i >= 0; i--) { if (m_SystemInputModules[i] && m_SystemInputModules[i].IsActive()) continue; m_SystemInputModules.RemoveAt(i); } } private bool m_SelectionGuard; public bool alreadySelecting { get { return m_SelectionGuard; } } public void SetSelectedGameObject(GameObject selected, BaseEventData pointer) { if (m_SelectionGuard) { Debug.LogError("Attempting to select " + selected + "while already selecting an object."); return; } m_SelectionGuard = true; if (selected == m_CurrentSelected) { m_SelectionGuard = false; return; } // Debug.Log("Selection: new (" + selected + ") old (" + m_CurrentSelected + ")"); ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.deselectHandler); m_CurrentSelected = selected; ExecuteEvents.Execute(m_CurrentSelected, pointer, ExecuteEvents.selectHandler); m_SelectionGuard = false; } private BaseEventData m_DummyData; private BaseEventData baseEventDataCache { get { if (m_DummyData == null) m_DummyData = new BaseEventData(this); return m_DummyData; } } public void SetSelectedGameObject(GameObject selected) { SetSelectedGameObject(selected, baseEventDataCache); } private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs) { if (lhs.module != rhs.module) { var lhsEventCamera = lhs.module.eventCamera; var rhsEventCamera = rhs.module.eventCamera; if (lhsEventCamera != null && rhsEventCamera != null && lhsEventCamera.depth != rhsEventCamera.depth) { // need to reverse the standard compareTo if (lhsEventCamera.depth < rhsEventCamera.depth) return 1; if (lhsEventCamera.depth == rhsEventCamera.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 (lhs.depth != rhs.depth) return rhs.depth.CompareTo(lhs.depth); if (lhs.distance != rhs.distance) return lhs.distance.CompareTo(rhs.distance); return lhs.index.CompareTo(rhs.index); } #region 射线检测 private static readonly Comparison s_RaycastComparer = RaycastComparer; // 从PointerInputModule.GetTouchPointerEventData()来的触摸数据 public void RaycastAll(PointerEventData eventData, List raycastResults) { raycastResults.Clear(); //包括场景中所有的raycaster var modules = RaycasterManager.GetRaycasters(); for (int i = 0; i < modules.Count; ++i) { var module = modules[i]; if (module == null || !module.IsActive()) continue; module.Raycast(eventData, raycastResults); } raycastResults.Sort(s_RaycastComparer); } #endregion //c 是否点击到某个物体 public bool IsPointerOverGameObject() { return IsPointerOverGameObject(PointerInputModule.kMouseLeftId); } //c 是否点击到某个物体 public bool IsPointerOverGameObject(int pointerId) { if (m_CurrentInputModule == null) return false; return m_CurrentInputModule.IsPointerOverGameObject(pointerId); } protected override void OnEnable() { base.OnEnable(); if (EventSystem.current == null) EventSystem.current = this; #if UNITY_EDITOR else { Debug.LogWarning("Multiple EventSystems in scene... this is not supported"); } #endif } protected override void OnDisable() { if (m_CurrentInputModule != null) { m_CurrentInputModule.DeactivateModule(); m_CurrentInputModule = null; } if (EventSystem.current == this) EventSystem.current = null; base.OnDisable(); } protected virtual void OnApplicationFocus(bool hasFocus) { m_HasFocus = hasFocus; } private void TickModules() { // 只有standaloneInputModule一个 for (var i = 0; i < m_SystemInputModules.Count; i++) { if (m_SystemInputModules[i] != null) m_SystemInputModules[i].UpdateModule(); } } //c 事件处理跑在一个update里,以轮训的方式检测输入 protected virtual void Update() { if (current != this) return; // 只更新鼠标位置 TickModules(); // 将m_CurrentInputModule设置为m_SystemInputModules第一个可用的module bool changedModule = false; for (var i = 0; i < m_SystemInputModules.Count; i++) { var module = m_SystemInputModules[i]; if (module.IsModuleSupported() && module.ShouldActivateModule()) { if (m_CurrentInputModule != module) { ChangeEventModule(module); changedModule = true; } break; } } // no event module set... set the first valid one... if (m_CurrentInputModule == null) { for (var i = 0; i < m_SystemInputModules.Count; i++) { var module = m_SystemInputModules[i]; if (module.IsModuleSupported()) { ChangeEventModule(module); changedModule = true; break; } } } //c! 执行事件处理主入口,通常情况下,如果没有自定义的inputModule,就是走StandaloneInputModule的Process if (!changedModule && m_CurrentInputModule != null) m_CurrentInputModule.Process(); } private void ChangeEventModule(BaseInputModule module) { if (m_CurrentInputModule == module) return; if (m_CurrentInputModule != null) m_CurrentInputModule.DeactivateModule(); if (module != null) module.ActivateModule(); m_CurrentInputModule = module; } public override string ToString() { var sb = new StringBuilder(); sb.AppendLine("Selected:" + currentSelectedGameObject); sb.AppendLine(); sb.AppendLine(); sb.AppendLine(m_CurrentInputModule != null ? m_CurrentInputModule.ToString() : "No module"); return sb.ToString(); } } }