基于Unity的事件中心系统EventCenter,用于集中管理游戏内的事件监听与触发。

先贴代码和用法

EventCenter

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public interface IEventInfo
{

}

public class EventInfo<T> : IEventInfo
{
    public UnityAction<T> actions = delegate { };
    public EventInfo(UnityAction<T> action)
    {
        actions += action;
    }
}

public class EventInfo : IEventInfo

{
    public UnityAction actions = delegate { };

    public EventInfo(UnityAction action)
    {
        actions += action;
    }
}

public class EventCenter : MonoBehaviour
{
    public static EventCenter Instance;

    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this;
        DontDestroyOnLoad(gameObject);
    }

    Dictionary<GameEvent, IEventInfo> eventDict = new Dictionary<GameEvent, IEventInfo>();

    //触发事件
    public void EventTrigger(GameEvent gameEvent)
    {
        if (eventDict.ContainsKey(gameEvent))
        {
            (eventDict[gameEvent] as EventInfo).actions?.Invoke();
        }
    }

    public void EventTrigger<T>(GameEvent gameEvent, T value)
    {
        if (eventDict.ContainsKey(gameEvent))
        {
            //Debug.Log(eventDict[gameEvent]);
            (eventDict[gameEvent] as EventInfo<T>).actions?.Invoke(value);
        }
    }


    #region 添加事件监听器
    public void AddEventListener(GameEvent gameEvent, UnityAction action)
    {
        if (eventDict.ContainsKey(gameEvent))
        {
            (eventDict[gameEvent] as EventInfo).actions += action;
        }
        else
        {
            eventDict.Add(gameEvent, new EventInfo(action) as IEventInfo);
        }
    }

    public void AddEventListener<T>(GameEvent gameEvent, UnityAction<T> action)
    {
        if (eventDict.ContainsKey(gameEvent))
        {
            (eventDict[gameEvent] as EventInfo<T>).actions += action;
        }
        else
        {
            eventDict.Add(gameEvent, new EventInfo<T>(action) as IEventInfo);
        }
    }
    #endregion

    #region 移除事件添加器
    public void RemoveEventListener(GameEvent gameEvent, UnityAction action)
    {
        if (eventDict.ContainsKey(gameEvent))
        {
            (eventDict[gameEvent] as EventInfo).actions -= action;
        }
    }

    public void RemoveEventListener<T>(GameEvent gameEvent, UnityAction<T> action)
    {
        if (eventDict.ContainsKey(gameEvent))
        {
            (eventDict[gameEvent] as EventInfo<T>).actions -= action;
        }
    }

    #endregion

    //清空事件
    public void Clear()
    {
        eventDict.Clear();
    }
}

需要搭配一个GameEvent的枚举一起使用

可以单独定义一个类用于存储枚举

GameEvent

public enum GameEvent
{
    游戏失败,
    角色阵亡,
    游戏胜利,
}

具体用法

1.在需要触发的脚本中通过AddEventListener 添加对特定逻辑函数的订阅,将函数订阅到枚举的类型上

    private void Start()
    {
        EventCenter.Instance.AddEventListener(GameEvent.游戏失败, GameOver);
    }

    private void OnDestroy()
    {
        EventCenter.Instance.RemoveEventListener(GameEvent.游戏失败, GameOver);
    }

    private void GameOver()
    {
        //写你想被触发的逻辑
        //...
    }

2.在想要触发的地方使用EventTrigger 即可触发添加到枚举中的事件

if(hp < 0)
{
    EventCenter.Instance.EventTrigger(GameEvent.游戏失败);
}
if(player.transform.position.y < -5f)
{
    EventCenter.Instance.EventTrigger(GameEvent.游戏失败);
}

这样可以在不同的地方都可以触发事件,简洁明了

核心结构解析

1. 事件信息容器(EventInfo类)
  • IEventInfo接口:空接口,作为类型标识,用于统一管理不同参数类型的事件容器。

  • 泛型容器EventInfo<T>:存储带参数的事件回调(UnityAction<T>),构造函数将传入的回调添加到委托链。

  • 无参容器EventInfo:存储无参数的事件回调(UnityAction),设计逻辑与泛型版本一致。

2. 单例事件中心(EventCenter类)
  • 单例模式:通过Awake方法确保全局唯一实例,跨场景不销毁(DontDestroyOnLoad)。

  • 事件字典eventDict:以GameEvent(应为枚举类型)为键,存储对应的事件信息容器。

3. 事件触发与监听
  • 触发事件EventTrigger方法通过事件类型查找并调用对应的委托链,支持无参和泛型参数。

  • 添加/移除监听:通过AddEventListenerRemoveEventListener注册或解绑回调,自动处理委托链的增减。

关键设计点

1. 泛型与接口的灵活运用
  • 通过IEventInfo接口统一管理不同参数类型的事件容器,利用类型转换在触发时调用具体委托,平衡了类型安全与灵活性。

2. 委托链的默认初始化
  • 委托初始化为delegate { },避免空引用异常,无需每次触发前检查null

3. 单例全局访问
  • 事件中心作为单例,方便任何脚本通过EventCenter.Instance访问,确保事件系统的全局一致性

总结

该事件中心通过单例模式和泛型设计,提供了简洁高效的事件管理机制,适用于Unity项目的解耦需求。开发者需注意事件类型的一致性和监听的生命周期管理,以确保系统稳定运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

变身缎带

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值