游戏事件中心:解耦模块的利器
事件中心模块
事件中心的主要作用是 解耦程序模块,降低程序耦合度,它可以降低游戏中不同模块的耦合度,不需要直接引用或依赖于彼此的具体实现
事件中心的基本原理 通过一个中心化的机制,使得多个系统、模块、对象之间可以进行松耦合的通信,我们只需要利用字典和委托相关的知识点,再结合观察者设计模式的基本原理便可以制作出事件中心模块
观察者设计模式:其主要原理是定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都能够得到通知并自动更新
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;/// <summary>
/// 事件中心模块
/// </summary>
public class EventCenter : BaseManager<EventCenter>
{//用于记录对应事件 关联的 对应的逻辑private Dictionary<string, UnityAction> eventDic = new Dictionary<string, UnityAction>();private EventCenter() { }/// <summary>/// 触发事件/// </summary>/// <param name="eventName"></param>public void EventTrigger(string eventName){//存在等待当前事件执行的函数 才去通知别人处理逻辑if (eventDic.ContainsKey(eventName)){eventDic[eventName]?.Invoke();}}/// <summary>/// 添加事件监听者/// </summary>/// <param name="eventName"></param>/// <param name="func"></param>public void AddEventListener(string eventName, UnityAction func){//如果存在关心事件的委托记录 直接添加即可if (eventDic.ContainsKey(eventName)){eventDic[eventName] += func;}else{eventDic.Add(eventName,null);eventDic[eventName] += func;}}/// <summary>/// 移除事件监听者/// </summary>/// <param name="eventName"></param>/// <param name="func"></param>public void RemoveEventListener(string eventName, UnityAction func){if (eventDic.ContainsKey(eventName)){eventDic[eventName] -= func;}}/// <summary>/// 清除所有事件监听/// </summary>public void Clear(){ eventDic.Clear();}/// <summary>/// 清除指定的事件监听/// </summary>/// <param name="eventName"></param>public void Clear(string eventName){ if(eventDic.ContainsKey(eventName))eventDic.Remove(eventName);}
}
传递参数优化
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;//用于里氏替换原则 装载 子类的父类
public abstract class EventInfoBase { }
//用来包裹 对应观察者 函数委托的 类
public class EventInfo<T> : EventInfoBase
{ //真正观察者对应的信息记录在其中public UnityAction<T> actions;
}
/// <summary>
/// 主要用来记录无参的委托
/// </summary>
public class EventInfo: EventInfoBase
{//真正观察者对应的信息记录在其中public UnityAction actions;
}
/// <summary>
/// 事件中心模块
/// </summary>
public class EventCenter : BaseManager<EventCenter>
{//用于记录对应事件 关联的 对应的逻辑private Dictionary<string, EventInfoBase> eventDic = new Dictionary<string, EventInfoBase>();private EventCenter() { }/// <summary>/// 触发事件/// </summary>/// <param name="eventName"></param>public void EventTrigger<T>(string eventName,T info){//存在等待当前事件执行的函数 才去通知别人处理逻辑if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo<T>).actions?.Invoke(info);}}public void EventTrigger(string eventName){//存在等待当前事件执行的函数 才去通知别人处理逻辑if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo).actions?.Invoke();}}/// <summary>/// 添加事件监听者/// </summary>/// <param name="eventName"></param>/// <param name="func"></param>public void AddEventListener<T>(string eventName, UnityAction<T> func){//如果存在关心事件的委托记录 直接添加即可if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo<T>).actions += func;}else{eventDic.Add(eventName,new EventInfo<T>());(eventDic[eventName] as EventInfo<T>).actions += func;}}public void AddEventListener(string eventName, UnityAction func){//如果存在关心事件的委托记录 直接添加即可if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo).actions += func;}else{eventDic.Add(eventName, new EventInfo());(eventDic[eventName] as EventInfo).actions += func;}}/// <summary>/// 移除事件监听者/// </summary>/// <param name="eventName"></param>/// <param name="func"></param>public void RemoveEventListener<T>(string eventName, UnityAction<T> func){if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo<T>).actions -= func;}}public void RemoveEventListener(string eventName, UnityAction func){if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo).actions -= func;}}/// <summary>/// 清除所有事件监听/// </summary>public void Clear(){ eventDic.Clear();}/// <summary>/// 清除指定的事件监听/// </summary>/// <param name="eventName"></param>public void Clear(string eventName){ if(eventDic.ContainsKey(eventName))eventDic.Remove(eventName);}
}
事件名优化
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;/// <summary>
/// 事件类型枚举
/// </summary>
public enum E_EventType
{ /// <summary>/// 怪物死亡事件/// </summary>E_Monster_Dead,/// <summary>/// 玩家获取奖励/// </summary>E_Player_GetReward,
}//用于里氏替换原则 装载 子类的父类
public abstract class EventInfoBase { }
//用来包裹 对应观察者 函数委托的 类
public class EventInfo<T> : EventInfoBase
{ //真正观察者对应的信息记录在其中public UnityAction<T> actions;
}
/// <summary>
/// 主要用来记录无参的委托
/// </summary>
public class EventInfo: EventInfoBase
{//真正观察者对应的信息记录在其中public UnityAction actions;
}
/// <summary>
/// 事件中心模块
/// </summary>
public class EventCenter : BaseManager<EventCenter>
{//用于记录对应事件 关联的 对应的逻辑private Dictionary<E_EventType, EventInfoBase> eventDic = new Dictionary<E_EventType, EventInfoBase>();private EventCenter() { }/// <summary>/// 触发事件/// </summary>/// <param name="eventName"></param>public void EventTrigger<T>(E_EventType eventName,T info){//存在等待当前事件执行的函数 才去通知别人处理逻辑if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo<T>).actions?.Invoke(info);}}public void EventTrigger(E_EventType eventName){//存在等待当前事件执行的函数 才去通知别人处理逻辑if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo).actions?.Invoke();}}/// <summary>/// 添加事件监听者/// </summary>/// <param name="eventName"></param>/// <param name="func"></param>public void AddEventListener<T>(E_EventType eventName, UnityAction<T> func){//如果存在关心事件的委托记录 直接添加即可if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo<T>).actions += func;}else{eventDic.Add(eventName,new EventInfo<T>());(eventDic[eventName] as EventInfo<T>).actions += func;}}public void AddEventListener(E_EventType eventName, UnityAction func){//如果存在关心事件的委托记录 直接添加即可if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo).actions += func;}else{eventDic.Add(eventName, new EventInfo());(eventDic[eventName] as EventInfo).actions += func;}}/// <summary>/// 移除事件监听者/// </summary>/// <param name="eventName"></param>/// <param name="func"></param>public void RemoveEventListener<T>(E_EventType eventName, UnityAction<T> func){if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo<T>).actions -= func;}}public void RemoveEventListener(E_EventType eventName, UnityAction func){if (eventDic.ContainsKey(eventName)){(eventDic[eventName] as EventInfo).actions -= func;}}/// <summary>/// 清除所有事件监听/// </summary>public void Clear(){ eventDic.Clear();}/// <summary>/// 清除指定的事件监听/// </summary>/// <param name="eventName"></param>public void Clear(E_EventType eventName){ if(eventDic.ContainsKey(eventName))eventDic.Remove(eventName);}
}
测试
被观察者 调用函数触发事件
public class lesson5 : MonoBehaviour
{public string name = "xxxx";public int id = 0;// Start is called before the first frame updatevoid Start(){Dead();}public void Dead(){print("Dead");EventCenter.Instance.EventTrigger<lesson5>(E_EventType.E_Monster_Dead,this);}}观察者 注册添加事件,销毁后删除事件
public class lesson5_1 : MonoBehaviour
{// Start is called before the first frame updatevoid Awake(){EventCenter.Instance.AddEventListener<lesson5>(E_EventType.E_Monster_Dead, Test);}public void Test(lesson5 lesson){print("lesson5_1" + lesson.name);}private void OnDestroy(){EventCenter.Instance.RemoveEventListener<lesson5>(E_EventType.E_Monster_Dead, Test);}
}结果

