首先写一个最基本的事件中心模块,可以接受参数
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class EventCenter : BaseManager<EventCenter>
{
private Dictionary<string, UnityAction<object>> eventDic = new Dictionary<string, UnityAction<object>>();
public void EventTrigger(string name, object message)
{
if (eventDic.ContainsKey(name))
{
eventDic[name]?.Invoke(message);
}
}
public void AddEventListener(string name, UnityAction<object> act)
{
if (eventDic.ContainsKey(name))
{
eventDic[name] += act;
}
else
{
eventDic.Add(name, act);
}
}
public void RemoveEventListener(string name, UnityAction<object> act)
{
if (eventDic.ContainsKey(name))
{
eventDic[name] -= act;
}
}
}
虽然此模块已经可以实现基本的功能,但是由于参数类型为object类型,在使用过程中还是会进行装箱拆箱相关的转换,还会耗费一定的性能。所以考虑使用泛型来代替使用obejct做参数传递
using System.Collections;
using System.Collections.Generic;
using UnityEditor.VersionControl;
using UnityEngine;
using UnityEngine.Events;
public interface IEventType { }
public class EventType<T> : IEventType
{
public UnityAction<T> actions;
public EventType(UnityAction<T> act)
{
actions += act;
}
}
public class EventType : IEventType
{
public UnityAction actions;
public EventType(UnityAction act)
{
actions += act;
}
}
public class EventCenter : BaseManger<EventCenter>
{
private Dictionary<string, IEventType> eventDic = new Dictionary<string, IEventType>();
public void EventTrigger<T>(string name, T message)
{
if (eventDic.ContainsKey(name))
{
(eventDic[name] as EventType<T>).actions?.Invoke(message);
}
}
public void EventTrigger(string name)
{
if (eventDic.ContainsKey(name))
{
(eventDic[name] as EventType).actions?.Invoke();
}
}
public void AddEventListener<T>(string name, UnityAction<T> act)
{
if (eventDic.ContainsKey(name))
{
(eventDic[name] as EventType<T>).actions += act;
}
else
{
eventDic.Add(name, new EventType<T>(act));
}
}
public void AddEventListener(string name, UnityAction act)
{
if (eventDic.ContainsKey(name))
{
(eventDic[name] as EventType).actions += act;
}
else
{
eventDic.Add(name, new EventType(act));
}
}
public void RemoveEventListener<T>(string name, UnityAction<T> act)
{
if (eventDic.ContainsKey(name))
{
(eventDic[name] as EventType<T>).actions -= act;
}
}
public void RemoveEventListener(string name, UnityAction act)
{
if (eventDic.ContainsKey(name))
{
(eventDic[name] as EventType).actions -= act;
}
}
}
因为希望该模块不用挂载到实际物体身上就能使用,所以让EventType<T> 继承 IEventType接口。利用里氏转换原则,即可正常向字典里添加泛型版本的类对象
使用例:
public class A
{
public string name;
}
...
EventCenter.GetInstance().AddEventListener<A>("A类监听", (arg) =>
{
//具体逻辑
print(arg.name);
});
...
A a = new a();
a.name = "啦啦啦";
EventCenter.GetInstance().EventTrigger<A>("A类监听", a);