unity事件相关整理

发表于2018-06-26
评论5 5k浏览

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





如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: