265 lines
7.5 KiB
C#
265 lines
7.5 KiB
C#
using System;
|
|
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.1f;
|
|
|
|
[Header("指针图片")] public Sprite defaultCursor;
|
|
public Sprite nextTalk, talking, option, interactive, holding, disable, eye;
|
|
|
|
private Image _cursor;
|
|
|
|
#region 状态相关
|
|
|
|
private Coroutine _switchCoroutine;
|
|
private CursorState _curState = CursorState.Default;
|
|
private bool _isTalking;
|
|
[HideInInspector] public bool isInMenu;
|
|
|
|
#endregion
|
|
|
|
// 卸载时注销事件
|
|
private readonly 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>();
|
|
}
|
|
|
|
private void RegisterEvent()
|
|
{
|
|
// 此处监听所有可能对鼠标状态产生影响的事件
|
|
RegisterDialogEvent();
|
|
RegisterTriggerEvent();
|
|
RegisterMenu();
|
|
}
|
|
|
|
private void RegisterDialogEvent()
|
|
{
|
|
// 对话相关
|
|
_unRegisters.Add(EnumEventSystem.Global.Register<DialogEventEnum, DialogText>(DialogEventEnum.LineStart,
|
|
OnLineStart));
|
|
_unRegisters.Add(EnumEventSystem.Global.Register(DialogEventEnum.LineShowed, () => SwitchCursor(nextTalk)));
|
|
_unRegisters.Add(EnumEventSystem.Global.Register(DialogEventEnum.LineEnd, OnLineEnd));
|
|
_unRegisters.Add(EnumEventSystem.Global.Register(DialogEventEnum.OptionShow, OnOptionShow));
|
|
_unRegisters.Add(
|
|
EnumEventSystem.Global.Register<DialogEventEnum, DialogText>(DialogEventEnum.OptionSelected,
|
|
OnOptionSelect));
|
|
}
|
|
|
|
private void RegisterTriggerEvent()
|
|
{
|
|
// 交互相关
|
|
_unRegisters.Add(EnumEventSystem.Global.Register(InteractionEventEnum.Start, OnInteractiveStart));
|
|
_unRegisters.Add(EnumEventSystem.Global.Register(InteractionEventEnum.End, OnInteractiveEnd));
|
|
|
|
_unRegisters.Add(
|
|
EnumEventSystem.Global.Register<TriggerEnum, IInteraction>(TriggerEnum.PointerEnter, OnPointerEnter));
|
|
_unRegisters.Add(
|
|
EnumEventSystem.Global.Register<TriggerEnum, IInteraction>(TriggerEnum.PointerExit, OnPointerExit));
|
|
_unRegisters.Add(
|
|
EnumEventSystem.Global.Register<TriggerEnum, IInteraction>(TriggerEnum.PointerDown, OnPointerDown));
|
|
_unRegisters.Add(
|
|
EnumEventSystem.Global.Register<TriggerEnum, IInteraction>(TriggerEnum.PointerUp, OnPointerUp));
|
|
}
|
|
|
|
private void RegisterMenu()
|
|
{
|
|
_unRegisters.Add(EnumEventSystem.Global.Register<EventEnum, bool>(EventEnum.Menu, OnMenuChange));
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
|
|
{
|
|
if (_isTalking && !isInMenu)
|
|
{
|
|
DialogController.Instance.JumpLine();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
// // 将虚拟指针与鼠标位置同步
|
|
// RectTransformUtility.ScreenPointToLocalPointInRectangle(_cursorCanvas, Input.mousePosition,
|
|
// CameraKit.Instance.uiCamera, out var worldPos);
|
|
|
|
_cursor.rectTransform.position = Input.mousePosition;
|
|
|
|
// 在输入状态,要单独处理
|
|
}
|
|
|
|
#region 对话相关
|
|
|
|
private void OnLineStart(DialogText line)
|
|
{
|
|
_isTalking = true;
|
|
SwitchCursor(talking);
|
|
}
|
|
|
|
private void OnLineEnd()
|
|
{
|
|
StopDelayCursor();
|
|
_switchCoroutine = StartCoroutine(DelayAction(() =>
|
|
{
|
|
_isTalking = false;
|
|
_cursor.sprite = defaultCursor;
|
|
}));
|
|
}
|
|
|
|
private void OnOptionShow()
|
|
{
|
|
_isTalking = true;
|
|
SwitchCursor(option);
|
|
}
|
|
|
|
private void OnOptionSelect(DialogText line)
|
|
{
|
|
StopDelayCursor();
|
|
_switchCoroutine = StartCoroutine(DelayAction(() =>
|
|
{
|
|
_isTalking = false;
|
|
_cursor.sprite = defaultCursor;
|
|
}));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 交互相关
|
|
|
|
private void OnInteractiveStart()
|
|
{
|
|
_curState = CursorState.Interactive;
|
|
if (EventSystemEx.Instance.pointerOverObj)
|
|
{
|
|
SwitchCursor(interactive);
|
|
}
|
|
}
|
|
|
|
private void OnInteractiveEnd()
|
|
{
|
|
_curState = CursorState.Default;
|
|
// 退出时把Cursor置为Default
|
|
SwitchCursor(defaultCursor);
|
|
}
|
|
|
|
private void OnPointerEnter(IInteraction target)
|
|
{
|
|
if (_curState == CursorState.Interactive && !_isTalking)
|
|
{
|
|
// 如果不可交互,就显示不可交互的指针
|
|
SwitchCursor(target.IsActive ? interactive : disable);
|
|
}
|
|
}
|
|
|
|
private void OnPointerExit(IInteraction target)
|
|
{
|
|
if (_curState == CursorState.Interactive && !_isTalking)
|
|
{
|
|
SwitchCursor(defaultCursor);
|
|
}
|
|
}
|
|
|
|
private void OnPointerDown(IInteraction target)
|
|
{
|
|
if (_curState == CursorState.Interactive && !_isTalking)
|
|
{
|
|
SwitchCursor(target.IsActive ? holding : defaultCursor);
|
|
}
|
|
}
|
|
|
|
private void OnPointerUp(IInteraction target)
|
|
{
|
|
if (_curState == CursorState.Interactive && !_isTalking)
|
|
{
|
|
// 如果松手时还在物体之上
|
|
SwitchCursor(EventSystemEx.Instance.holdingObj == target.GetGameObject() ? interactive : defaultCursor);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
#region 菜单打开
|
|
|
|
private void OnMenuChange(bool isMenuOpen)
|
|
{
|
|
isInMenu = isMenuOpen;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 指针切换
|
|
|
|
/// <summary>
|
|
/// 直接切指针
|
|
/// </summary>
|
|
/// <param name="sprite">指针图片</param>
|
|
private void SwitchCursor(Sprite sprite)
|
|
{
|
|
StopDelayCursor();
|
|
_cursor.sprite = sprite;
|
|
}
|
|
|
|
private void StopDelayCursor()
|
|
{
|
|
if (_switchCoroutine != null)
|
|
{
|
|
StopCoroutine(_switchCoroutine);
|
|
_switchCoroutine = null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
private static IEnumerator DelayAction(Action action)
|
|
{
|
|
yield return new WaitForSeconds(DelayTime);
|
|
action.Invoke();
|
|
}
|
|
}
|
|
|
|
public enum CursorState
|
|
{
|
|
Default,
|
|
Interactive,
|
|
Eye
|
|
}
|
|
} |