Unity 游戏框架搭建 (五) 简易消息机制
来源:互联网 发布:linux域名绑定公网ip 编辑:程序博客网 时间:2024/05/29 12:36
什么是消息机制?
23333333,让我先笑一会。
为什么用消息机制?
三个字,解!!!!耦!!!!合!!!!。
我的框架中的消息机制用例:
1.接收者
using UnityEngine; using System.Collections;using QFramework;/// <summary>/// 1.接收者需要实现IMsgReceiver接口。/// 2.使用this.RegisterLogicMsg注册消息和回调函数。/// </summary>public class Receiver : MonoBehaviour,IMsgReceiver { void Awake() { this.RegisterLogicMsg ("Receiver Show Sth", ReceiverMsg);// this.UnRegisterLogicMsg ("Receiver Show Sth", ReceiverMsg); } void ReceiverMsg(params object[] paramList) { foreach (var sth in paramList) { QPrint.Warn (sth.ToString()); } }}
2.发送者
using UnityEngine; using System.Collections; using QFramework;/// <summary>/// 1.发送者需要,实现IMsgSender接口/// 2.调用this.SendLogicMsg发送Receiver Show Sth消息,并传入两个参数/// </summary>public class Sender : MonoBehaviour,IMsgSender { // Update is called once per frame void Update () { this.SendLogicMsg ("Receiver Show Sth","你好","世界"); }}
3.运行结果
使用起来几行代码的事情,实现起来就没这么简单了。
如何实现的?
可以看到接收者实现了接口IMsgReceiver,发送者实现了接口IMsgSender。 那先看下这两个接口定义。
IMsgReceiver:
using UnityEngine; using System.Collections;namespace QFramework { public interface IMsgReceiver { }}
IMsgSender
using UnityEngine; using System.Collections;namespace QFramework { public interface IMsgSender { }}
毛都没有啊。也没有SendLogicMsg或者ReceiveLogicMsg方法的定义啊。
答案是使用C# this的扩展方式实现接口方法。 不清楚的童鞋请百度C# this扩展,有好多文章就不介绍了。 以上先告一段落,先介绍个重要的角色,MsgDispatcher(消息分发器)。
贴上第一部分代码:
namespace QFramework { /// <summary> /// 消息分发器 /// C# this扩展 需要静态类 /// </summary> public static class QMsgDispatcher { /// <summary> /// 消息捕捉器 /// </summary> class LogicMsgHandler { public IMsgReceiver receiver; public VoidDelegate.WithParams callback; /* * VoidDelegate.WithParams 是一种委托 ,定义是这样的 * * public class VoidDelegate{ * public delegate void WithParams(params object[] paramList); * } */ public LogicMsgHandler(IMsgReceiver receiver,VoidDelegate.WithParams callback) { this.receiver = receiver; this.callback = callback; } } /// <summary> /// 每个消息名字维护一组消息捕捉器。 /// </summary> static Dictionary<string,List<LogicMsgHandler>> mMsgHandlerDict = new Dictionary<string,List<LogicMsgHandler>> ();
读注释!!!
贴上注册消息的代码
/// <summary> /// 注册消息, /// 注意第一个参数,使用了C# this的扩展, /// 所以只有实现IMsgReceiver的对象才能调用此方法 /// </summary> public static void RegisterLogicMsg(this IMsgReceiver self, string msgName,VoidDelegate.WithParams callback) { // 略过 if (string.IsNullOrEmpty(msgName)) { QPrint.FrameworkWarn("RegisterMsg:" + msgName + " is Null or Empty"); return; } // 略过 if (null == callback) { QPrint.FrameworkWarn ("RegisterMsg:" + msgName + " callback is Null"); return; } // 略过 if (!mMsgHandlerDict.ContainsKey (msgName)) { mMsgHandlerDict [msgName] = new List<LogicMsgHandler> (); } // 看下这里 var handlers = mMsgHandlerDict [msgName]; // 略过 // 防止重复注册 foreach (var handler in handlers) { if (handler.receiver == self && handler.callback == callback) { QPrint.FrameworkWarn ("RegisterMsg:" + msgName + " ayready Register"); return; } } // 再看下这里 handlers.Add (new LogicMsgHandler (self, callback)); }
为了节省您时间,略过部分的代码就不要看了,什么?!!你都看了!!!! 23333
发送消息相关的代码
/// <summary> /// 发送消息 /// 注意第一个参数 /// </summary> public static void SendLogicMsg(this IMsgSender sender, string msgName,params object[] paramList ) { // 略过,不用看 if (string.IsNullOrEmpty(msgName)) { QPrint.FrameworkError("SendMsg is Null or Empty"); return; } // 略过,不用看 if (!mMsgHandlerDict.ContainsKey(msgName)){ QPrint.FrameworkWarn("SendMsg is UnRegister"); return; } // 开始看!!!! var handlers = mMsgHandlerDict[msgName]; var handlerCount = handlers.Count; // 之所以是从后向前遍历,是因为 从前向后遍历删除后索引值会不断变化 // 参考文章,http://www.2cto.com/kf/201312/266723.html for (int index = handlerCount - 1;index >= 0;index--) { var handler = handlers[index]; if (handler.receiver != null) { QPrint.FrameworkLog ("SendLogicMsg:" + msgName + " Succeed"); handler.callback (paramList); } else { handlers.Remove (handler); } } }
OK主要的部分全都贴出来啦
以上代码以全部上传到Github上边
贴出代码地址:消息机制相关代码地址
可以改进的地方:
1.目前整个游戏的消息都由一个字典维护,可以改进为每个模块维护一个字典或者其他方式。 2.消息名字类型由字符串定义的,可以改成枚举转unsigned int方式。 3.欢迎补充。
坑
1.如果是MonoBehaviour注册消息之后,GameObject Destroy之前一定要注销消息,之前的解决方案是,自定义一个基类来维护该对象已经注册的消息列表,然后在基类的OnDestory时候遍历卸载。 2.欢迎补充。
阅读全文
0 0
- Unity 游戏框架搭建 (五) 简易消息机制
- Unity 游戏框架搭建 (五) 简易消息机制
- Unity 游戏框架搭建 (五) 简易消息机制
- Unity 游戏框架搭建--简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (十一) 简易AssetBundle打包工具(一)
- Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
- Unity 游戏框架搭建 (十一) 简易AssetBundle打包工具(一)
- Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
- Unity 游戏框架搭建 (十一) 简易AssetBundle打包工具(一)
- Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)
- Unity游戏UI框架(五):配置管理
- Unity 客户端框架(三):消息机制
- Unity 游戏框架搭建 (一) 概述
- Unity 游戏框架搭建 (一) 概述
- 【设计模式】适配器模式
- 【iOS】View跳转和传值
- 【Shader实战篇】PBR贴图之Normal Map贴图
- N
- 数字图像处理——用Java对数字图像写水印
- Unity 游戏框架搭建 (五) 简易消息机制
- 在Winform中向DataGridView控件添加数据的三种方式
- 错误提示:Unable to connect to adb.Check if adb is installed correctly
- 同步阻塞通信-伪异步I/O编程
- 安装mongodb复制集
- Unity 游戏框架搭建 (六) 关于框架的一些好文和一些思考
- rpc
- Android中的信息输出:System.out和Log的源码分析与对比(Log篇)
- php剔除emoji表情符号