using AibisDream.Framework; using AibisDream.Kit; using UnityEngine; using UnityEngine.UI; namespace AibisDream { public class CursorManager : Singleton { [SerializeField] private GameObject border; [Header("指针图片")] public Sprite defaultCursor; public Sprite nextTalk, talking, option, interactive, holding, rotating, disable; private Image _cursor; private Object _interactionCursorOwner; private CursorStateEnum _interactionCursorState; private bool _cursorVisible = true; private void Start() { border.SetActive(true); InitRefs(); #if UNITY_ANDROID || UNITY_IOS _cursor.gameObject.SetActive(false); #else InitCursor(); #endif } public void SetCursorVisible(bool visible) { #if UNITY_ANDROID || UNITY_IOS return; #endif _cursorVisible = visible; ApplyCursorVisibility(); } private void ApplyCursorVisibility() { if (_cursor != null) { _cursor.gameObject.SetActive(_cursorVisible); } // 隐藏自定义指针图时显示系统真实指针,便于录制等场景定位鼠标 Cursor.visible = !_cursorVisible; } private void InitCursor() { Cursor.visible = false; _cursor.sprite = defaultCursor; } private void InitRefs() { _cursor = transform.Find("Cursor").GetComponent(); } private void LateUpdate() { #if !(UNITY_ANDROID || UNITY_IOS) // // 将虚拟指针与鼠标位置同步 // RectTransformUtility.ScreenPointToLocalPointInRectangle(_cursorCanvas, Input.mousePosition, // CameraKit.Instance.uiCamera, out var worldPos); // 判断当前要用什么样的指针 _cursor.rectTransform.position = Input.mousePosition; var cursorState = CheckCursorState(); _cursor.sprite = GetCursorSprite(cursorState); #endif } private CursorStateEnum CheckCursorState() { var gameState = GameManager.Session; if (gameState.Phase != GameSessionPhase.Playing || gameState.IsPaused) { // 非游戏中显示默认指针 return CursorStateEnum.Default; } else if (UIManager.Instance.IsOverRegion("MainUI")) { // 游戏中鼠标移至右上角Main Panel时显示默认指针 return CursorStateEnum.Default; } else if (gameState.IsDialogueActive) { // 处理对话中的指针 var dialogState = DialogController.Instance.GetDialogState(); return HandleDialogState(dialogState); } else { // 非对话处理指针交互 if (_interactionCursorOwner != null) { return _interactionCursorState; } var triggerEnum = EventSystemEx.Instance.GetPointerState(); return HandleDraggingState(triggerEnum); } } private CursorStateEnum HandleDialogState(LineSyncState dialogState) { return dialogState switch { LineSyncState.Default => CursorStateEnum.Default, LineSyncState.PlayText => CursorStateEnum.PlayText, LineSyncState.AdvanceDelay => CursorStateEnum.PlayText, LineSyncState.WaitForAdvance => CursorStateEnum.WaitForAdvance, LineSyncState.WaitForAutoAdvance => CursorStateEnum.WaitForAdvance, LineSyncState.Advanced => CursorStateEnum.Default, LineSyncState.InOption => CursorStateEnum.InOption, _ => CursorStateEnum.Default, }; } private CursorStateEnum HandleDraggingState(TriggerEnum triggerEnum) { return triggerEnum switch { TriggerEnum.Dragging => CursorStateEnum.Dragging, TriggerEnum.PointerOver => CursorStateEnum.PointerOver, _ => CursorStateEnum.Default, }; } private Sprite GetCursorSprite(CursorStateEnum cursorState) { return cursorState switch { CursorStateEnum.Default => defaultCursor, CursorStateEnum.PlayText => talking, CursorStateEnum.WaitForAdvance => nextTalk, CursorStateEnum.InOption => option, CursorStateEnum.Dragging => holding, CursorStateEnum.PointerOver => interactive, CursorStateEnum.Rotating => rotating != null ? rotating : interactive, _ => defaultCursor, }; } public void SetInteractionCursor(Object owner, CursorStateEnum state) { if (owner == null) return; _interactionCursorOwner = owner; _interactionCursorState = state; } public void ClearInteractionCursor(Object owner) { if (owner != null && _interactionCursorOwner != owner) return; _interactionCursorOwner = null; _interactionCursorState = CursorStateEnum.Default; } } public enum CursorStateEnum { Default, PlayText, WaitForAdvance, InOption, Dragging, PointerOver, Rotating } }