Files
aibis-dream/Assets/Scripts/UI/Cursor/CursorManager.cs
T
2025-01-16 11:37:14 +08:00

153 lines
4.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using AibisDream.Framework;
using UnityEngine;
using UnityEngine.UI;
namespace AibisDream
{
public class CursorManager : MonoBehaviour
{
private const float DelayTime = 0.2f;
[Header("指针图片")] public Sprite defaultCursor;
public Sprite nextTalk, talking, option, interactive, holding, disable, eye;
private Image _cursor;
private RectTransform _cursorCanvas;
#region 状态相关
private Coroutine _switchCoroutine;
private CursorState _curState = CursorState.Default;
#endregion
// 卸载时注销事件
private List<IUnRegister> _unRegisters = new();
public void Awake()
{
InitRefs();
InitCursor();
}
private void InitCursor()
{
Cursor.visible = false;
SwitchCursor(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>();
_cursorCanvas = GetComponent<RectTransform>();
}
private void RegisterEvent()
{
// 此处监听所有可能对鼠标状态产生影响的事件
// 对话相关
_unRegisters.Add(EnumEventSystem.Global.Register<DialogEventEnum, DialogLine>(DialogEventEnum.LineStart,
_ => SwitchCursor(talking)));
_unRegisters.Add(EnumEventSystem.Global.Register(DialogEventEnum.LineShowed, () => SwitchCursor(nextTalk)));
_unRegisters.Add(EnumEventSystem.Global.Register(DialogEventEnum.LineEnd,
() => SwitchCursorDelay(defaultCursor)));
_unRegisters.Add(EnumEventSystem.Global.Register(DialogEventEnum.OptionShow, () => SwitchCursor(option)));
_unRegisters.Add(
EnumEventSystem.Global.Register<DialogEventEnum, DialogLine>(DialogEventEnum.OptionSelected,
_ => SwitchCursorDelay(defaultCursor)));
// 交互相关
_unRegisters.Add(EnumEventSystem.Global.Register(InteractionEventEnum.Start, OnInteractiveStart));
_unRegisters.Add(EnumEventSystem.Global.Register(InteractionEventEnum.End, OnInteractiveEnd));
}
private void LateUpdate()
{
// 将虚拟指针与鼠标位置同步
RectTransformUtility.ScreenPointToLocalPointInRectangle(_cursorCanvas, Input.mousePosition,
CameraKit.Instance.uiCamera, out var worldPos);
_cursor.rectTransform.localPosition = worldPos;
// 在输入状态,要单独处理
}
#region 交互状态相关
private void OnInteractiveStart()
{
_curState = CursorState.Interactive;
}
private void OnInteractiveEnd()
{
_curState = CursorState.Interactive;
}
#endregion
#region 指针切换
/// <summary>
/// 直接切指针
/// </summary>
/// <param name="sprite">指针图片</param>
private void SwitchCursor(Sprite sprite)
{
StopDelayCursor();
_cursor.sprite = sprite;
}
/// <summary>
/// 延迟切换指针。如果后面有其他切换状态,就直接打断
/// </summary>
/// <param name="sprite">指针图片</param>
private void SwitchCursorDelay(Sprite sprite)
{
StopDelayCursor();
_switchCoroutine = StartCoroutine(SwitchCursorAsync(sprite));
}
private IEnumerator SwitchCursorAsync(Sprite sprite)
{
yield return new WaitForSeconds(DelayTime);
_cursor.sprite = sprite;
}
private void StopDelayCursor()
{
if (_switchCoroutine != null)
{
StopCoroutine(_switchCoroutine);
_switchCoroutine = null;
}
}
#endregion
}
public enum CursorState
{
Default,
Interactive,
Eye
}
}