赞
踩
目录
Unity 工具类 之 简单的消息机制 MessageCenter 实现
Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。
消息机制,也可以叫做观察者设计模式;通俗易懂点讲,就是 一个物体发出消息,另外一个,或者几个物体可以同时接收到这一消息并作出各自不同的行为(反馈,处理)。
1、消息机制中引入了事件机制,事件机制其实是一种叫做观察者模式的设计模式,事件的本质是一种方法的委托(Delegate),把回调方法委托到事件管理器,当条件达到时,通过事件key来告诉事件管理器可以执行那些委托的方法。
2、单例类,保证整个场景中只有一个类管理消息;把消息统一在一起注册、发送和移除;
3、MessageCenter.Instance.RegisterListener 注册消息;
4、MessageCenter.Instance.SendMessage 发送消息;
5、MessageCenter.Instance.RemoveListener 移除消息;
1、为了避免 MessageCenter 单例被 new ,所以在 MessageCenter 中把 无参构造函数私有化;
2、一个消息可注册多个事件;
1、打开Unity,新建一个工程,如下图
2、在工程中新建脚本,Singleton 实现单例类,Message 消息(可以根据需要拓展),MessageCenter 消息中心管理消息的注册发送与移除(可以根据需要拓展),Test_MessageCenter 测试消息机制脚本、如下图
3、在场景中添加测试脚本,进行消息机制的测试,如下图
4、测试效果如下图
1、Singleton
- using System;
- using System.Reflection;
-
- /// <summary>
- /// 单例
- /// 继承需要一个非公有的无参构造函数
- /// </summary>
- /// <typeparam name="T">类名的泛型</typeparam>
- public abstract class Singleton<T> where T : class
- {
- private static T instance = null;
-
- // 多线程安全机制
- private static readonly object locker = new object();
-
- public static T Instance
- {
- get
- {
- // 线程锁
- lock (locker)
- {
- if (null == instance)
- {
- // 反射获取实例
- var octors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) ;
-
- // 获取无参数的非公共构造函数
- var octor = Array.Find(octors, c => c.GetParameters().Length == 0);
-
- // 没有则提示没有私有的构造函数
- if (null == octor)
- {
- throw new Exception("No NonPublic constructor without 0 parameter");
- }
-
- // 实例化
- instance = octor.Invoke(null) as T;
- }
-
- return instance;
-
- }
- }
- }
-
- /// <summary>
- /// 构造函数
- /// 避免外界new
- /// </summary>
- protected Singleton() { }
- }
2、Message
-
-
- /// <summary>
- /// 消息类
- /// </summary>
- public class Message
- {
- public int Type //发送的消息类型
- {
- get;
- private set;
- }
- public object Body //消息主体
- {
- get;
- private set;
- }
-
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="type">消息类型</param>
- /// <param name="body">消息体</param>
- public Message(int type, object body)
- {
- Type = type;
- Body = body;
- }
- }
3、MessageCenter
-
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
-
- /// <summary>
- /// 消息的类型
- /// </summary>
- public enum MessageType
- {
- /// <summary>
- /// 启动
- /// </summary>
- START_UP = 1000,
- /// <summary>
- /// 解压
- /// </summary>
- UNPACK,
- /// <summary>
- /// 更新
- /// </summary>
- UPDATE,
- /// <summary>
- /// 更新完成
- /// </summary>
- UPDATE_COMPLETE,
- }
-
-
- /// <summary>
- /// 战斗的类型
- /// </summary>
- public enum BattleEvent
- {
- /// <summary>
- /// 攻击
- /// </summary>
- Attack = 10000,
- }
-
- /// <summary>
- /// 协议的类型
- /// </summary>
- public enum ProtocolEvent
- {
-
- }
-
-
- /// <summary>
- /// 消息中心
- /// </summary>
- public class MessageCenter : Singleton<MessageCenter>
- {
- // 消息委托
- public delegate void messageDelHandle(Message message);
- // 消息字典
- private Dictionary<int, messageDelHandle> messageMap = new Dictionary<int, messageDelHandle>();
-
- /// <summary>
- /// 构造函数
- /// 避免外界new
- /// </summary>
- private MessageCenter() { }
-
- /// <summary>
- /// 注册监听
- /// </summary>
- public void RegisterListener(int messageType, messageDelHandle handle)
- {
- if (handle == null) return;
-
- // 把事件添加到对应的委托中
- messageDelHandle myHandle = null;
- messageMap.TryGetValue(messageType, out myHandle);
- messageMap[messageType] = (messageDelHandle)Delegate.Combine(myHandle, handle);
-
- }
- /// <summary>
- /// 移除监听
- /// </summary>
- public void RemoveListener(int messageType, messageDelHandle handle)
- {
- if (handle == null) return;
- messageMap[messageType] = (messageDelHandle)Delegate.Remove(messageMap[messageType], handle);
- }
-
- /// <summary>
- /// 清空消息
- /// </summary>
- public void Clear()
- {
- messageMap.Clear();
- }
- /// <summary>
- /// 发送消息
- /// </summary>
- /// <param name="messageName">消息类型 </param>
- /// <param name="body"> 发送消息主体 </param>
- public void SendMessage(int messageType, object body = null)
- {
-
- messageDelHandle handle;
- if (messageMap.TryGetValue(messageType, out handle))
- {
- Message evt = new Message(messageType, body);
- try
- {
- if (handle != null)
- {
- handle(evt);
- }
- }
- catch (System.Exception e)
- {
- Debug.Print("SendMessage:", evt.Type.ToString(), e.Message, e.StackTrace, e);
- }
- }
-
- }
-
- #region 枚举类型接口
-
- #region MessageType
- public void RegisterListener(MessageType messageType, messageDelHandle handle) {
- RegisterListener((int)messageType, handle);
- }
- public void RemoveListener(MessageType messageType, messageDelHandle handle)
- {
- RemoveListener((int) messageType, handle);
- }
- public void SendMessage(MessageType messageType, object body = null) {
- SendMessage((int)messageType, body);
- }
- #endregion
-
-
- #region BattleEvent
- public void RegisterListener(BattleEvent messageType, messageDelHandle handle)
- {
- RegisterListener((int)messageType, handle);
- }
- public void RemoveListener(BattleEvent messageType, messageDelHandle handle)
- {
- RemoveListener((int)messageType, handle);
- }
- public void SendMessage(BattleEvent messageType, object body = null)
- {
- SendMessage((int)messageType, body);
- }
- #endregion
-
-
- #region ProtocolEvent
- public void RegisterListener(ProtocolEvent messageType, messageDelHandle handle)
- {
- RegisterListener((int)messageType, handle);
- }
- public void RemoveListener(ProtocolEvent messageType, messageDelHandle handle)
- {
- RemoveListener((int)messageType, handle);
- }
- public void SendMessage(ProtocolEvent messageType, object body = null)
- {
- SendMessage((int)messageType, body);
- }
-
- #endregion
-
- #endregion
- }
4、Test_MessageCenter
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Test_MessageCenter : MonoBehaviour
- {
- // Start is called before the first frame update
- void Start()
- {
-
-
- MessageCenter.Instance.RegisterListener(MessageType.START_UP, StartUp); //注册
- MessageCenter.Instance.RegisterListener(MessageType.START_UP, StartUp2); //注册
-
-
- }
-
- // Update is called once per frame
- void Update()
- {
-
- if (Input.GetKeyDown(KeyCode.A)) {
-
- MessageCenter.Instance.SendMessage(MessageType.START_UP,this.gameObject);
- }
-
- if (Input.GetKeyDown(KeyCode.D))
- {
-
- MessageCenter.Instance.RemoveListener(MessageType.START_UP, StartUp2);
- }
- }
-
-
- private void StartUp(Message message)
- {
- Debug.Log("游戏启动");
- Debug.Log(message.Type);
- Debug.Log(message.Body);
-
-
- }
-
- private void StartUp2(Message message)
- {
- Debug.Log("游戏启动2");
- Debug.Log(message.Type);
- Debug.Log(message.Body);
-
-
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。