67 lines
2.5 KiB
C#
67 lines
2.5 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
namespace Architecture.Core
|
|
{
|
|
/// <summary>
|
|
/// 无参事件通道(ScriptableObject 资产)。
|
|
/// 系统 / UI 在 Inspector 中拖入同一个资产实例即可实现解耦通信,
|
|
/// 彻底替代 static Action 事件与单例方法调用。
|
|
/// 注意:资产实例是项目级资源,跨场景天然存活,无需 DontDestroyOnLoad。
|
|
/// </summary>
|
|
[CreateAssetMenu(menuName = "Architecture/Events/Game Event", fileName = "NewGameEvent")]
|
|
public class GameEvent : ScriptableObject
|
|
{
|
|
private readonly List<GameEventListener> _listeners = new List<GameEventListener>();
|
|
private event System.Action _codeListeners;
|
|
|
|
public void Raise()
|
|
{
|
|
// Inspector 监听器(设计师配置的 UnityEvent 响应)优先于代码监听器触发,
|
|
// 保证表现层(UI 动画/音效)在逻辑层之前响应事件。
|
|
for (int i = _listeners.Count - 1; i >= 0; i--)
|
|
_listeners[i].OnEventRaised();
|
|
_codeListeners?.Invoke();
|
|
}
|
|
|
|
/// <summary>Inspector 监听器(GameEventListener 组件)注册。</summary>
|
|
public void RegisterListener(GameEventListener listener)
|
|
{
|
|
if (!_listeners.Contains(listener)) _listeners.Add(listener);
|
|
}
|
|
|
|
public void UnregisterListener(GameEventListener listener)
|
|
{
|
|
if (_listeners.Contains(listener)) _listeners.Remove(listener);
|
|
}
|
|
|
|
/// <summary>代码监听器(Action)注册,便于 MonoBehaviour 在 OnEnable 中订阅,
|
|
/// 是替换 static Action 事件的主要入口。</summary>
|
|
public void Register(System.Action listener)
|
|
{
|
|
if (listener != null) _codeListeners += listener;
|
|
}
|
|
|
|
public void Unregister(System.Action listener)
|
|
{
|
|
if (listener != null) _codeListeners -= listener;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 无参事件监听器(设计师友好,纯 Inspector 配置)。
|
|
/// 监听某个 GameEvent,触发时调用绑定的 UnityEvent 响应。
|
|
/// </summary>
|
|
public class GameEventListener : MonoBehaviour
|
|
{
|
|
[SerializeField] private GameEvent _event;
|
|
[SerializeField] private UnityEvent _response;
|
|
|
|
private void OnEnable() => _event?.RegisterListener(this);
|
|
private void OnDisable() => _event?.UnregisterListener(this);
|
|
|
|
public void OnEventRaised() => _response?.Invoke();
|
|
}
|
|
}
|