unity事件相关整理
发表于2018-06-26
1.原生事件
监听:
![]()
触发:
![]()
回调:
![]()
可带参数,参考:https://docs.unity3d.com/ScriptReference/Events.UnityEvent.html
2.委托
委托是一种特殊类型的对象。
委托类:

实际运用中可将各种委托都放到这里面来,方便统一查找。
上面委托类中有一个负责消息传递,我们用它来传递文本消息,操作如下:

运行输出:

3.事件自定义实现
以上原生事件和委托实现的事件,都会使用起来相对麻烦甚至冗余等等,管理起来也比较复杂,比如我们需要创建各种继承UnityEvent类的其他类,需要增加各种委托去区分处理等等。
为了更友好、更方便的实现事件管理,下面来介绍自定义实现方式:
目地:接口友好、使用方便、管理简单!
需求:注册事件addListener、派发事件dispatch、移除事件removeListener,等。
实现:提供一个单例事件中心的类EventCenter

使用:

结果:

EventCenter主要代码:
private Dictionary<object, Dictionary<string, List<Action<object, object>>>> frameEventMap = new Dictionary<object, Dictionary<string, List<Action<object, object>>>>();
public void addListener(object target, string eventName, Action<object, object> handler)
{
Dictionary<string, List<Action<object, object>>> targetMap;
List<Action<object, object>> handlerList;
Debug.Log("addListener target:" + target + " , eventName:" + eventName);
if (frameEventMap.ContainsKey(target) == false)
{
targetMap = new Dictionary<string, List<Action<object, object>>>();
frameEventMap[target] = targetMap;
}
targetMap = frameEventMap[target];
if (targetMap.ContainsKey(eventName) == false)
{
handlerList = new List<Action<object, object>>();
targetMap[eventName] = handlerList;
}
handlerList = targetMap[eventName];
if (getHandlerInfo(handlerList, handler) == null)
{
handlerList.Add(handler);
Debug.Log("addListener ok");
}
}
public void removeListener(object target, string eventName, Action<object,object> handler)
{
if (frameEventMap.ContainsKey(target) == false)
{
return;
}
Dictionary<string, List<Action<object, object>>> targetMap = frameEventMap[target];
if (targetMap.ContainsKey(eventName) == false)
{
return;
}
List<Action<object, object>> handlerList = targetMap[eventName];
Action<object,object> handlerListInfo = getHandlerInfo(handlerList, handler);
if (handlerListInfo != null)
{
handlerList.Remove(handler);
Debug.Log("removeListener target:" + target + ", eventName:" + eventName);
}
}
public void dispatch(string eventName, object arg1 = null, object arg2 = null)
{
Dictionary<string,List<Action<object,object>>> targetMap;
List<Action<object, object>> handlerList;
foreach (var item in frameEventMap)
{
targetMap = item.Value;
if (targetMap!=null && targetMap.ContainsKey(eventName))
{
handlerList = targetMap[eventName];
if (handlerList != null)
{
foreach (Action<object, object> testHandler in handlerList)
{
if (testHandler != null)
{
Debug.Log("dispatch ok,[eventName:" + eventName + ",arg1:" + arg1 + ",arg2:" + arg2 + "]");
testHandler.Invoke(arg1, arg2);
}
}
}
}
}
}
private Action<object, object> getHandlerInfo(List<Action<object, object>> handlerList, Action<object, object> handler)
{
foreach (Action<object, object> testHandler in handlerList)
{
if (testHandler == handler)
{
return testHandler;
}
}
return null;
}
