148 lines
3.9 KiB
C#
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
|
|
}
|
|
} |