开发模块2——事件中心模块
事件中心模块,基于观察者模式
代码部分:unity的实现
三大部分脚本:事件中心(出版社),发布者,订阅者(杂七杂八的);
要求:增添删除事件委托,调用事件都在事件中心,订阅者与发布者不互相直接关联
主体:事件中心:
- 使用Dictionary存储不同的需要监听的事件(杂志)
- 含有订阅AddEventListener与删除订阅RemoveEventListener的函数
- 含EventTrigger,用于存储需要发布的方法(杂志)
- 提供清空Dictionary的clear方法,(主要用于切换场景时调用)
次要 发布者:调用事件中心的引用·从而调用EventTrigger(发布杂志,从而引起订阅者反应)
订阅者:调用事件中心的引用·从而调用Add订阅或remove取消(注:当物体销毁时,记得要Remove)
代码详情
主体:事件中心
using UnityEngine.Events;
public class EventCenter:test1<EventCenter>//继承自单例类
{
private Dictionary<string, UnityAction<object>> eventDic = new Dictionary<string, UnityAction<object>>();//用object当万能参数,有装箱拆箱,但游戏中参数传递多半是引用类,故消耗比较少
public void AddEventListener(string eventName, UnityAction<object> action)//eventName要监听的事件名;需要反应的函数
{
if(eventDic.ContainsKey(eventName))//是否存在该事件
{
eventDic[eventName] += action;
}
else//无则加入新事件
{
eventDic.Add(eventName, action);
}
}
public void RemoveEventListener(string eventName, UnityAction<object> action)
{
if(eventDic.ContainsKey(eventName))
{
eventDic[eventName] -= action;
}
}
public void EventTrigger(string eventName,object obj)
{ if (eventDic.ContainsKey(eventName))
{
eventDic[eventName]?.Invoke(obj);//?号确保还有订阅者,等同于以下语句
// if(eventDic[eventName]!=null)//
//{
//eventDic[eventName](obj);
//}
}
}
public void clear()
{
eventDic.Clear();
}
}
次要:发布者
public class Writer : MonoBehaviour
{
private int price = 3;
void Start()
{
Invoke("Issue", 3f);//注:要保证所有订阅者已经订阅再发售(此处用的是invoke延迟发售,也可以把订阅者的订阅从start提前到Onable)
}
void Issue()
{
EventCenter.GetInstance().EventTrigger("public book",price);
}
}
订阅者一号
public class reader1 : MonoBehaviour
{
int money;
void Start()
{
money = 3;
EventCenter.GetInstance().AddEventListener("public book", BuyBook);//若发布了书,则购买
}
void BuyBook(object price)
{
money -=(int)price;
Debug.Log("剩余的钱"+money);
}
private void OnDestroy()//若当前物体被摧毁,则取消订阅
{
EventCenter.GetInstance().RemoveEventListener("public book", BuyBook);
}
}