using System.Collections.Generic; using System.Linq; using AibisDream.Framework; using AibisDream.Kit; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace AibisDream { public class CursorManager : Singleton { [SerializeField] private GameObject border; [Header("指针图片")] public Sprite defaultCursor; public Sprite nextTalk, talking, option, interactive, holding, disable; private Image _cursor; private GraphicRaycaster _raycaster; private CursorState _stateCache; #region 状态相关 private Coroutine _switchCoroutine; private CursorState _curState = CursorState.Default; private bool _isTalking; private bool _isInGame; #endregion // 卸载时注销事件 private readonly List _unRegisters = new(); private void Start() { border.SetActive(true); InitRefs(); InitCursor(); } private void InitCursor() { Cursor.visible = false; _cursor.sprite = defaultCursor; } private void OnEnable() { RegisterEvent(); } private void OnDisable() { // 注销所有事件 foreach (var eventUnRegister in _unRegisters) { eventUnRegister.UnRegister(); } _unRegisters.Clear(); } private void InitRefs() { _cursor = transform.Find("Cursor").GetComponent(); _raycaster = UIManager.Instance.Canvas.GetComponent(); } private void RegisterEvent() { // 此处监听所有可能对鼠标状态产生影响的事件 RegisterGameEvent(); } private void RegisterGameEvent() { _unRegisters.Add(EnumEventSystem.Global.Register(GameLoopEnum.GameStart, OnGameStart)); _unRegisters.Add(EnumEventSystem.Global.Register(GameLoopEnum.GameQuit, OnGameQuit)); _unRegisters.Add(EnumEventSystem.Global.Register(GameLoopEnum.PauseGame, OnPauseGame)); _unRegisters.Add(EnumEventSystem.Global.Register(GameLoopEnum.UnPauseGame, OnUnPauseGame)); } private void OnGameStart() { _isInGame = true; } private void OnUnPauseGame() { _curState = _stateCache; _stateCache = CursorState.Default; _isInGame = true; } private void OnPauseGame() { _stateCache = _curState; _curState = CursorState.Default; _isInGame = false; } private void OnGameQuit() { _curState = CursorState.Default; _stateCache = CursorState.Default; _isInGame = false; } private bool IsOverSelected() { if (!EventSystem.current.IsPointerOverGameObject()) { return false; } var eventData = new PointerEventData(EventSystem.current) { position = Input.mousePosition }; var results = new List(); _raycaster.Raycast(eventData, results); return results.Count > 0 && results.Any(result => result.gameObject.CompareTag("Selectable")); } private void LateUpdate() { // // 将虚拟指针与鼠标位置同步 // RectTransformUtility.ScreenPointToLocalPointInRectangle(_cursorCanvas, Input.mousePosition, // CameraKit.Instance.uiCamera, out var worldPos); _cursor.rectTransform.position = Input.mousePosition; // 在输入状态,要单独处理 } } public enum CursorState { Default, Interactive } }