217 lines
6.3 KiB
C#
217 lines
6.3 KiB
C#
using System.Collections.Generic;
|
|
using System;
|
|
using AibisDream.Kit;
|
|
using UnityEngine;
|
|
|
|
namespace AibisDream.Framework
|
|
{
|
|
public class EventSystemEx : Singleton<EventSystemEx>
|
|
{
|
|
#region 状态
|
|
|
|
public bool isLocked;
|
|
private bool _dialogueLocked;
|
|
private int _scopedLockDepth;
|
|
|
|
#endregion
|
|
|
|
private List<GameObject> pointerOverObjList;
|
|
private List<GameObject> draggingObjList;
|
|
private List<GameObject> holdingObjList;
|
|
|
|
#region 事件触发中转
|
|
|
|
public void OnPointerEnter(IInteraction interaction)
|
|
{
|
|
if (!pointerOverObjList.Contains(interaction.GetGameObject()))
|
|
{
|
|
pointerOverObjList.Add(interaction.GetGameObject());
|
|
}
|
|
}
|
|
|
|
public void OnPointerExit(IInteraction interaction)
|
|
{
|
|
pointerOverObjList.Remove(interaction.GetGameObject());
|
|
}
|
|
|
|
public void OnPointerDown(IInteraction interaction)
|
|
{
|
|
if (!holdingObjList.Contains(interaction.GetGameObject()))
|
|
{
|
|
holdingObjList.Add(interaction.GetGameObject());
|
|
}
|
|
}
|
|
|
|
public void OnPointerUp(IInteraction interaction)
|
|
{
|
|
holdingObjList.Remove(interaction.GetGameObject());
|
|
}
|
|
|
|
public void OnDrag(IInteraction interaction)
|
|
{
|
|
if (!draggingObjList.Contains(interaction.GetGameObject()))
|
|
{
|
|
draggingObjList.Add(interaction.GetGameObject());
|
|
}
|
|
}
|
|
|
|
public void OnEndDrag(IInteraction interaction)
|
|
{
|
|
draggingObjList.Remove(interaction.GetGameObject());
|
|
}
|
|
|
|
public void OnBeginDrag(IInteraction interaction)
|
|
{
|
|
if (!draggingObjList.Contains(interaction.GetGameObject()))
|
|
{
|
|
draggingObjList.Add(interaction.GetGameObject());
|
|
}
|
|
}
|
|
|
|
public TriggerEnum GetPointerState()
|
|
{
|
|
if (holdingObjList.Count > 0 || draggingObjList.Count > 0)
|
|
{
|
|
return TriggerEnum.Dragging;
|
|
}
|
|
else if (pointerOverObjList.Count > 0)
|
|
{
|
|
return TriggerEnum.PointerOver;
|
|
}
|
|
else
|
|
{
|
|
return TriggerEnum.None;
|
|
}
|
|
}
|
|
|
|
public void UnRegister(IInteraction interaction)
|
|
{
|
|
pointerOverObjList.Remove(interaction.GetGameObject());
|
|
draggingObjList.Remove(interaction.GetGameObject());
|
|
holdingObjList.Remove(interaction.GetGameObject());
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 兜底:鼠标左键已抬起时强制清空 holding/dragging。
|
|
/// 防止 EventTrigger 在 isLocked 时跳过 Up/EndDrag 清理后光标一直停在抓取。
|
|
/// </summary>
|
|
private void LateUpdate()
|
|
{
|
|
if (Input.GetMouseButton(0)) return;
|
|
|
|
if (holdingObjList.Count > 0)
|
|
holdingObjList.Clear();
|
|
if (draggingObjList.Count > 0)
|
|
draggingObjList.Clear();
|
|
}
|
|
|
|
private void HandleDialogueComplete()
|
|
{
|
|
_dialogueLocked = false;
|
|
RefreshLockState();
|
|
}
|
|
|
|
private void HandleDialogueStart()
|
|
{
|
|
_dialogueLocked = true;
|
|
RefreshLockState();
|
|
}
|
|
|
|
public IDisposable AcquireInteractionLock(string reason)
|
|
{
|
|
_scopedLockDepth++;
|
|
RefreshLockState();
|
|
Debug.Log(
|
|
$"[EventSystemEx] Acquire interaction lock: {reason ?? "(unspecified)"}, " +
|
|
$"depth={_scopedLockDepth}");
|
|
return new InteractionLockScope(this, reason);
|
|
}
|
|
|
|
private void ReleaseInteractionLock(string reason)
|
|
{
|
|
_scopedLockDepth = Math.Max(0, _scopedLockDepth - 1);
|
|
RefreshLockState();
|
|
Debug.Log(
|
|
$"[EventSystemEx] Release interaction lock: {reason ?? "(unspecified)"}, " +
|
|
$"depth={_scopedLockDepth}");
|
|
}
|
|
|
|
private void RefreshLockState()
|
|
{
|
|
isLocked = _dialogueLocked || _scopedLockDepth > 0;
|
|
}
|
|
|
|
#region 单例必须的代码
|
|
|
|
public override void OnSingletonInit()
|
|
{
|
|
pointerOverObjList = new List<GameObject>();
|
|
draggingObjList = new List<GameObject>();
|
|
holdingObjList = new List<GameObject>();
|
|
_dialogueLocked = false;
|
|
_scopedLockDepth = 0;
|
|
RefreshLockState();
|
|
|
|
EnumEventSystem.Global.Register(GameLifecycleEvent.SessionStarted, ClearAll);
|
|
EnumEventSystem.Global.Register(GameLifecycleEvent.SessionEnded, ClearAll);
|
|
|
|
EnumEventSystem.Global.Register(InteractionEventEnum.DialogEnd, HandleDialogueComplete);
|
|
EnumEventSystem.Global.Register(InteractionEventEnum.DialogStart, HandleDialogueStart);
|
|
}
|
|
|
|
private void ClearAll()
|
|
{
|
|
pointerOverObjList.Clear();
|
|
draggingObjList.Clear();
|
|
holdingObjList.Clear();
|
|
}
|
|
|
|
public override void OnSingletonDestroy()
|
|
{
|
|
EnumEventSystem.Global.UnRegister(GameLifecycleEvent.SessionStarted, ClearAll);
|
|
EnumEventSystem.Global.UnRegister(GameLifecycleEvent.SessionEnded, ClearAll);
|
|
|
|
EnumEventSystem.Global.UnRegister(InteractionEventEnum.DialogEnd, HandleDialogueComplete);
|
|
EnumEventSystem.Global.UnRegister(InteractionEventEnum.DialogStart, HandleDialogueStart);
|
|
|
|
_dialogueLocked = false;
|
|
_scopedLockDepth = 0;
|
|
RefreshLockState();
|
|
}
|
|
|
|
private sealed class InteractionLockScope : IDisposable
|
|
{
|
|
private EventSystemEx _owner;
|
|
private readonly string _reason;
|
|
|
|
public InteractionLockScope(EventSystemEx owner, string reason)
|
|
{
|
|
_owner = owner;
|
|
_reason = reason;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_owner == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_owner.ReleaseInteractionLock(_reason);
|
|
_owner = null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
public enum TriggerEnum
|
|
{
|
|
None,
|
|
Dragging,
|
|
PointerOver
|
|
}
|
|
}
|