using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.EventSystems; using XericLibrary.Runtime.MacroLibrary; namespace XericUI.Helper { /// /// UI输入系统帮助 /// public static class EventSystemHelper { #region 字段属性 private static int raycastResultsFrameIndex = -1; public static List raycastResults = new List(); #endregion #region 辅助功能 /// /// 根据重载可选覆盖返回的事件系统 /// /// /// private static EventSystem GetEventSystem(EventSystem overrideEventSystem = null) => overrideEventSystem == null ? EventSystem.current : overrideEventSystem; /// /// 当前是否步进帧 /// /// /// 保持状态 /// private static bool IsFrameIndexChange(ref int frameIndex, bool holdon = false) { if (frameIndex == Time.frameCount) return false; if (holdon) return true; frameIndex = Time.frameCount; return true; } #endregion #region 光标在其上 /// /// 判断当前光标是否处于任意UI对象上 /// /// /// public static bool IsPointerOverGameObject(EventSystem overrideEventSystem = null) { overrideEventSystem = GetEventSystem(overrideEventSystem); return overrideEventSystem.IsPointerOverGameObject(); } /// /// 自动更新射线监测 /// /// /// public static List GetRaycastAllResults(EventSystem overrideEventSystem = null) { if (!IsFrameIndexChange(ref raycastResultsFrameIndex)) return raycastResults; overrideEventSystem = GetEventSystem(overrideEventSystem); var pointerData = new PointerEventData(overrideEventSystem) { position = Input.mousePosition }; overrideEventSystem.RaycastAll(pointerData, raycastResults); return raycastResults; } /// /// 判断当前光标是否处于特定组件上 /// /// 返回找到的组件 /// 是否启用兼容性,当在所有击中的元素上找不到目标时,继续向上查找 /// /// /// public static bool IsPointerOverUIWithComponent(out T component, bool compatibility = true, EventSystem overrideEventSystem = null) where T : Component { var results = GetRaycastAllResults(overrideEventSystem); if (results.Count <= 0) { component = null; return false; } component = results .Select(a => a.gameObject.GetComponent()) .FirstOrDefault(a => a != null); if (compatibility && component == null) component = results[^1].gameObject.GetComponentInParent(); return component != null; } #endregion } }