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; }