Unity游戏事件系统

通过一个小Demo测试一个简单的通用事件管理系统

分两步,一个管理器,一个事件ID定义类

当然,还可以扩展,比如加上异步操作,消息类自定义等等

1. EventManager

using System;
using System.Collections.Generic;
using UnityEngine;

namespace Core.Scripts.Event
{
    /// <summary>
    /// 事件管理器
    /// 通用与UI 逻辑 数据等系统
    /// EventManager.SharedInstance.RegEventHandle(EventDefines.);
    /// </summary>
    public class EventManager
    {
        //public Action<object, object> EventHandler;
        public delegate void EventHandler(object param, object sender);

        protected Dictionary<int, List<EventHandler>> _events = null;

        private static EventManager _instance = null;

        public static EventManager SharedInstance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new EventManager();
                }
                return _instance;
            }
        }

        public EventManager()
        {
            //初始化事件容器,设置大小
            _events = new Dictionary<int, List<EventHandler>>(2048);
        }

        /// <summary>
        /// 注册事件和回调
        /// </summary>
        /// <param name="eventID"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public bool RegEventHandle(int eventID, EventHandler handler)
        {
            if (handler == null)
            {
                Debug.Log("未设置回调,添加事件失败,失败ID:" + eventID);
                return false;
            }
            List<EventHandler> handlerList = null;
            if (!_events.TryGetValue(eventID, out handlerList))
            {
                handlerList = new List<EventHandler>();
                _events[eventID] = handlerList;
            }
            else
            {
                if (IndexOf(handlerList, handler) >= 0)
                {
                    return true;
                }
            }
            handlerList.Add(handler);
            return true;
        }

        /// <summary>
        /// 注销事件的回调
        /// </summary>
        /// <param name="eventID"></param>
        /// <param name="handler"></param>
        public void UnRegEventHandle(int eventID, EventHandler handler)
        {
            if (handler == null)
            {
                return;
            }
            List<EventHandler> handlerList;
            if (_events.TryGetValue(eventID, out handlerList))
            {
                int eventIndex = IndexOf(handlerList, handler);
                if (eventIndex >= 0)
                {
                    handlerList.RemoveAt(eventIndex);
                    //_events[eventID].Remove(handler);
                }
            }
        }

        /// <summary>
        /// 清理某一个事件的回调
        /// </summary>
        /// <param name="eventID"></param>
        public void CleanHandler(int eventID)
        {
            List<EventHandler> list;
            if (_events.TryGetValue(eventID, out list))
            {
                list.Clear();
                _events.Remove(eventID);
            }
        }

        /// <summary>
        /// 清理所有的事件信息
        /// </summary>
        public void CleanAllHandler()
        {
            _events.Clear();
        }

        /// <summary>
        /// 推送消息,执行注册的回调
        /// </summary>
        /// <param name="eventID"></param>
        /// <param name="param"></param>
        /// <param name="sender"></param>
        public void PushEvent(int eventID, object param, object sender)
        {
            try
            {
                List<EventHandler> handlerList;
                if (_events.TryGetValue(eventID, out handlerList))
                {
                    if (handlerList != null && handlerList.Count > 0)
                    {
                        //执行所有的回调函数
                        for (int i = 0; i < handlerList.Count; i++)
                        {
                            try
                            {
                                handlerList[i](param, sender);
                            }
                            catch (Exception ex)
                            {
                                handlerList.RemoveAt(i);
                                i--;
                                Debug.LogError(ex.Message);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogError(ex.Message);
            }
        }

        /// <summary>
        /// 对比下回调函数列表,防止重复注册回调函数
        /// </summary>
        /// <param name="list"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        private int IndexOf(List<EventHandler> list, EventHandler handler)
        {
            if (list != null)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    if (list[i].Equals(handler))
                    {
                        return i;
                    }
                }
            }
            return -1;
        }
    }
}

2. EventDefines

namespace Core.Scripts.Event
{
    /// <summary>
    /// 事件消息的定义
    /// </summary>
    public class EventDefines
    {
        //基础ID
        public const int EVENT_CORE_BASE_ID = 0;
        //逻辑ID
        public const int EVENT_LOGIC_BASE_ID = 100000;
        //UI ID
        public const int EVENT_UI_BASE_ID = 200000;
        //....还可以加一些其他的事件基础ID,比如处理SDK,资源加载,LUA调用

        //基础消息,类似场景切换...
        public const int EID_CORE_SCENE_CHANGE = EVENT_CORE_BASE_ID + 101;
        //UI消息,类似开关登陆界面...
        public const int EID_UI_UILoginForm_OPEN = EVENT_UI_BASE_ID + 101;
        public const int EID_UI_UILoginForm_CLOSE = EVENT_UI_BASE_ID + 109;
        //逻辑消息,类似登陆界面的数据刷新...
        public const int EID_LOGIC_LOGIN_SUCC = EVENT_LOGIC_BASE_ID + 101;
        public const int EID_LOGIC_LOGIN_FAIL = EVENT_LOGIC_BASE_ID + 102;
    }
}

3. 测试类EventTest

using Core.Scripts.Event;
using UnityEngine;

namespace Assets.Scripts
{
    public class EventTest : MonoBehaviour
    {
        private void Awake()
        {
            //注册
            EventManager.SharedInstance.RegEventHandle(EventDefines.EID_UI_UILoginForm_OPEN, OnLoginFormOpen);
        }

        private void Start()
        {
            EventManager.SharedInstance.PushEvent(EventDefines.EID_UI_UILoginForm_OPEN, "开始登陆", null);
        }

        void OnLoginFormOpen(object param, object sender)
        {
            //TODO 发消息给服务器请求数据
            if (param != null)
            {
                Debug.Log(param.ToString());
            }
        }

        private void OnDisable()
        {
            //注销
            EventManager.SharedInstance.UnRegEventHandle(EventDefines.EID_UI_UILoginForm_OPEN, OnLoginFormOpen);
        }
    }
}

4. 输出日志

猜你喜欢

转载自blog.csdn.net/u013476751/article/details/122672153