using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; namespace Architecture.Core { /// /// 无参事件通道(ScriptableObject 资产)。 /// 系统 / UI 在 Inspector 中拖入同一个资产实例即可实现解耦通信, /// 彻底替代 static Action 事件与单例方法调用。 /// 注意:资产实例是项目级资源,跨场景天然存活,无需 DontDestroyOnLoad。 /// [CreateAssetMenu(menuName = "Architecture/Events/Game Event", fileName = "NewGameEvent")] public class GameEvent : ScriptableObject { private readonly List _listeners = new List(); 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(); } /// Inspector 监听器(GameEventListener 组件)注册。 public void RegisterListener(GameEventListener listener) { if (!_listeners.Contains(listener)) _listeners.Add(listener); } public void UnregisterListener(GameEventListener listener) { if (_listeners.Contains(listener)) _listeners.Remove(listener); } /// 代码监听器(Action)注册,便于 MonoBehaviour 在 OnEnable 中订阅, /// 是替换 static Action 事件的主要入口。 public void Register(System.Action listener) { if (listener != null) _codeListeners += listener; } public void Unregister(System.Action listener) { if (listener != null) _codeListeners -= listener; } } /// /// 无参事件监听器(设计师友好,纯 Inspector 配置)。 /// 监听某个 GameEvent,触发时调用绑定的 UnityEvent 响应。 /// 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(); } }