Unity自定义消息系统

前段时间,场景里面Inspector面板用类似UnityEvent实现的触发各种自定义事件有几个点欠缺:

1.没有统一,到处都是在Inspector面板拖拽很难找。

2.可能存在拖拽的信息或者修改了方法名、参数名自己也忘记了(我就是被这个给坑了QAQ)。

3.没有统一,不好后续管理。

所以尝试着写了个消息系统,自己做个记录,以防以后需要往其中新添加其他功能自己也忘记思路了,其实套路很简单,直接代码:

Part1:

1.可以看到管理中消息id用的int,这是为了方便和自定义的消息类型用枚举变量相互转换。TSingleton是一个单例模式的模板,实现方式很简单,就不再赘述。基本的方法就是注册、注销消息,所有监听者派发消息及对指定监听者发消息的重载函数。

2.代码中可能有的地方用了一些扩展方法和Lambda表达式:Unity扩展方法

 #region 事件类型

    public enum BaseEvent
    {
        Null,
        显示,
        隐藏,
    }

    #endregion

    public class EventSystem : TSingleton
    {
        private class MonoEvent
        {
            private List monoBases = new List();

            public MonoEvent(MonoBase monoBase)
            {
                monoBases.AddNoContainsItem(monoBase);
            }

            public void Add(MonoBase monoBase)
            {
                monoBases.AddNoContainsItem(monoBase);
            }

            public void Remove(MonoBase monoBase)
            {
                monoBases.RemoveContainsItem(monoBase);
            }

            public void SendMessage(int eventType,params object[] args)
            {
                monoBases.ForEach((mono) =>
                {
                    mono.OnReceiveMessage(eventType,args);
                });
            }

            public void SendMessage(MonoBase monoBase ,int eventType, params object[] args)
            {
                monoBases.ForEach((mono) =>
                {
                    if(mono == monoBase)
                        mono.OnReceiveMessage(eventType, args);
                });
            }
        }

        private Dictionary monoEvents = new Dictionary();

        public EventSystem() { }

        /// 
        /// 注册事件
        /// 
        /// 
        /// MonoBase监听的事件类型
        public void AddListener(MonoBase monoBase, params int[] eventID)
        {
            eventID.Foreach((id) =>
            {
                if (monoEvents.ContainsKey(id))
                    monoEvents[id].Add(monoBase);
                else
                {
                    MonoEvent monoEvent = new MonoEvent(monoBase);
                    monoEvents.Add(id, monoEvent);
                }
            });
        }

        /// 
        /// 发送指定的消息
        /// 
        /// 指定某个MonoBase
        /// 事件类型
        /// 传递参数
        public void SendMessage(MonoBase monoBase, int eventID, params object[] args)
        {
            if (monoEvents.ContainsKey(eventID))
                monoEvents[eventID].SendMessage(monoBase, eventID, args);
        }

        /// 
        /// 发送消息
        /// 
        /// 触发的事件类型
        /// 传递的参数
        public void SendMessage(int eventID,params object[] args)
        {
            if (monoEvents.ContainsKey(eventID))
                monoEvents[eventID].SendMessage(eventID, args);
        }

        /// 
        /// 注销事件
        /// 
        /// 
        public void RemoveListener(MonoBase monoBase)
        {
            foreach (KeyValuePair kv in monoEvents)
            {
                kv.Value.Remove(monoBase);
            }
        }
    }

Part2:可以看到我的消息系统并没有像大多数消息系统一样用委托把函数添加到字典里面管理,我个人觉得各有利弊把,我认为这样子发送消息时,给函数传递参数更加方便一些,也利用消息系统实现了解耦合,看个人把:

 /// 
    /// 需要基于消息系统发送、接收消息继承MonoBase
    /// 
    public class MonoBase : MonoBehaviour
    {
        /// 
        /// 注册显示、隐藏事件----------
        /// 
        protected void AddListenerBase()
        {
            EventSystem.Instance.AddListener(this, (int)BaseEvent.显示);
            EventSystem.Instance.AddListener(this, (int)BaseEvent.隐藏);
        }

        /// 
        /// 接受消息
        /// 
        /// 消息ID
        /// 传递的参数
        public virtual void OnReceiveMessage(int eventID,params object[] args)
        {
            switch (eventID)
            {
                case (int)BaseEvent.显示: OnShow(); break;
                case (int)BaseEvent.隐藏: OnHide(); break;
            }
        }
        
        protected virtual void OnShow()
        {

        }

        protected virtual void OnHide()
        {

        }

        private void OnDestroy()
        {
            EventSystem.Instance.RemoveListener(this);
        }
    }

以上,Over

你可能感兴趣的:(Unity,消息系统)