Files
aibis-dream/Assets/Scripts/UI/Cursor/CursorManager.cs
T
2025-11-05 23:59:55 +08:00

148 lines
3.9 KiB
C#

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<CursorManager>
{
[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<IUnRegister> _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<Image>();
_raycaster = UIManager.Instance.Canvas.GetComponent<GraphicRaycaster>();
}
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<RaycastResult>();
_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
}
}