Unity 游戏框架搭建 2017 (五) 简易消息机制

2023-11-02

什么是消息机制?

 

 

 

 

 

 

23333333,让我先笑一会。

为什么用消息机制?

三个字,解!!!!耦!!!!合!!!!。

我的框架中的消息机制用例:

1.接收者 Receiver.cs

using UnityEngine;

namespace QFramework.Example
{
    /// <summary>
    /// 教程地址:http://liangxiegame.com/post/5/
    /// </summary>
    public class Receiver : MonoBehaviour, IMsgReceiver
    {
        // Use this for initialization
        private void Awake()
        {
            this.RegisterLogicMsg("Receiver Show Sth", ReceiveMsg);
        }

        private void ReceiveMsg(object[] args)
        {
            foreach (var arg in args)
            {
                Log.I(arg);
            }
        }
    }
}

2.发送者

using UnityEngine;

namespace QFramework.Example
{
    /// <summary>
    /// 教程地址:http://liangxiegame.com/post/5/
    /// </summary>
    public class Sender : MonoBehaviour, IMsgSender
    {
        void Update()
        {
            this.SendLogicMsg("Receiver Show Sth", "你好", "世界");
        }
    }
}

3.运行结果

使用起来几行代码的事情,实现起来就没这么简单了。

如何实现的?

可以看到接收者实现了接口IMsgReceiver,发送者实现了接口 IMsgSender。 那先看下这两个接口定义。

IMsgReceiver.cs:

namespace QFramework 
{
    public interface IMsgReceiver
    {
    }
}

IMsgSender.cs:

namespace QFramework 
{
    public interface IMsgSender
    {
    }
}

毛都没有啊。也没有 SendLogicMsg 或者 ReceiveLogicMsg 方法的定义啊。

答案是使用 C# this 的扩展方式实现接口方法。

不清楚的童鞋请百度 C# this 扩展,有好多文章就不介绍了。

以上先告一段落,先介绍个重要的角色,MsgDispatcher (消息分发器)。

贴上第一部分代码:

    /// <summary>
    /// 消息分发器
    /// C# this扩展 需要静态类
    /// 教程地址:http://liangxiegame.com/post/5/
    public static class MsgDispatcher
    {
        /// <summary>
        /// 消息捕捉器
        /// </summary>
        private class LogicMsgHandler
        {
            public readonly IMsgReceiver Receiver;
            public readonly Action<object[]> Callback;

            public LogicMsgHandler(IMsgReceiver receiver, Action<object[]> callback)
            {
                Receiver = receiver;
                Callback = callback;
            }
        }

        /// <summary>
        /// 每个消息名字维护一组消息捕捉器。
        /// </summary>
        static readonly Dictionary<string, List<LogicMsgHandler>> mMsgHandlerDict =
            new Dictionary<string, List<LogicMsgHandler>>();

读注释!!!

贴上注册消息的代码

        /// <summary>
        /// 注册消息,
        /// 注意第一个参数,使用了C# this的扩展,
        /// 所以只有实现IMsgReceiver的对象才能调用此方法
        /// </summary>
        public static void RegisterLogicMsg(this IMsgReceiver self, string msgName, Action<object[]> callback)
        {
            // 略过
            if (string.IsNullOrEmpty(msgName))
            {
                Log.W("RegisterMsg:" + msgName + " is Null or Empty");
                return;
            }

            // 略过
            if (null == callback)
            {
                Log.W("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)
                {
                    Log.W("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))
            {
                Log.E("SendMsg is Null or Empty");
                return;
            }

            // 略过,不用看
            if (!mMsgHandlerDict.ContainsKey(msgName))
            {
                Log.W("SendMsg is UnRegister");
                return;
            }

            // 开始看!!!!
            var handlers = mMsgHandlerDict[msgName];
            var handlerCount = handlers.Count;

            // 之所以是从后向前遍历,是因为  从前向后遍历删除后索引值会不断变化
            // 参考文章,http://www.2cto.com/kf/201312/266723.html
            for (var index = handlerCount - 1; index >= 0; index--)
            {
                var handler = handlers[index];

                if (handler.Receiver != null)
                {
                    Log.W("SendLogicMsg:" + msgName + " Succeed");
                    handler.Callback(paramList);
                }
                else
                {
                    handlers.Remove(handler);
                }
            }
        }

OK 主要的部分全都贴出来啦。

可以改进的地方:

  • 目前整个游戏的消息都由一个字典维护,可以改进为每个模块维护一个字典或者其他方式。
  • 消息名字类型由字符串定义的,可以改成枚举转 unsigned int 方式。
  • 欢迎补充。

坑:

  • 如果是 MonoBehaviour 注册消息之后,GameObject Destroy 之前一定要注销消息,之前的解决方案是,自定义一个基类来维护该对象已经注册的消息列表,然后在基类的 OnDestory 时候遍历卸载。
  • 欢迎补充。

转载请注明地址:凉鞋的笔记:liangxiegame.com

更多内容

  • 关注公众号:liangxiegame 获取第一时间更新通知及更多的免费内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity 游戏框架搭建 2017 (五) 简易消息机制 的相关文章

  • netty实现websocket推送消息

    前言 由于http协议为应答模式的连接 无法保持长连接于是引入了websocket套接字长连接概念 能够保持数据持久性的交互 本篇文章将告知读者如何使用netty实现简单的消息推送功能 websocket请求头 GET HTTP 1 1 H
  • apt 安装nginx

    ubuntu和debain下的apt方式安装软件很方便 特别是对于新手安装和卸载nginx 由于nginx不能动态添加模块 所以会经常安装和卸载 升级 apt安装nginx方法 sudo apt add repository ppa ngi
  • 旋转轴、旋转矩阵、四元数之间相互转换

    1 旋转轴To四元数 假设某个旋转是绕单位向量 n n x n y n z n n x n y n z n nx ny nz 进行了角度为 theta 的旋转 那么这个旋转的四元数形式为 q c o s 2 n x s i n 2 n y
  • java排查一个线上死循环cpu暴涨的过程

    问题 打一个页面cpu暴涨 打开一次就涨100 一会系统就卡的不行了 排查方法 因为是线上的linux 没有用jvm监控工具rim链接上去 只好用命令排查 top cpu排序 一个java进程cpu到500 了 什么鬼 查到对应java进程
  • 通过反射获取对象的所有属性&&表格的行转对象

    获取对象的属性并赋值 获取对象的属性方法 getFields 获得某个类的所有的公共 public 的字段 包括父类中的字段 getDeclaredFields 获得某个类的所有声明的字段 即包括public private和protece
  • 【图解】ERP系统如何操作?具体步骤是什么?

    信息时代 对于企业来说 实现统筹化管理 提升办公效率 这就是管理的王道 那么 如何快速实现这一目标呢 这就离不开ERP系统的使用了 在这里 我们就以智邦国际ERP系统的基本操作为例 给大家讲述一下 1 登录系统 每个企业的员工 对计算机知识
  • Java对blob文件的保存和解析

    1 在Java中经常需要保存一个xml文件到数据中 这个时候blob是最好的选择 但是保存的时候发现可不是那么容易的 网上很多资料都是先保存一个空的数据 再一点点插入进去 InputStream in new FileInputStream
  • STM32F103系列定时器TIM2 产生多路PWM —占空比可修改

    STM32F103系列定时器TIM2 产生多路PWM 占空比可修改 一 查看手册 手册中标明 当PA0 PA3当做TIM2 PWM输出时需要打开重映射功能GPIO PinRemapConfig GPIO PartialRemap2 TIM2
  • 【转载】十进制小数转二进制小数方法

    十进制小数转二进制小数方法 十进制小数 二进制小数 方法 乘2取整 对十进制小数乘2得到的整数部分和小数部分 整数部分既是相应的二进制数码 再用2乘小数部分 之前乘后得到新的小数部分 又得到整数和小数部分 如此不断重复 直到小数部分为0或达
  • 很多人都不知道的监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法

    在实际的应用中 我们常常需要实现在移动app和浏览器中点击返回 后退 上一页等按钮实现自己的关闭页面 调整到指定页面或执行一些其它操作的 需求 那在代码中怎样监听当点击微信 支付宝 百度糯米 百度钱包等app的返回按钮或者浏览器的上一页或后
  • STM32进入Standby模式并唤醒

    项目背景 设备具备电池 电源适配器两种供电方式 实现出厂 和电池一并密封装盒 时最低功耗 即进入待机模式 到用户开始使用时需要手动磁棒唤醒 开始复位运行 在检测到设备是交流供电时 设备全速运行 检测到是电池供电时 定时采集数据 采集完毕进入
  • JS逆向:Webpack打包后的代码怎么搞?猿人学爬虫比赛第十六题详细题解

    实战地址 http match yuanrenxue com match 16 抓包分析 地址栏输入 地址 按下F12并回车 发现数据在这里 查看cookie 无加密相关的字段 请求的接口倒是有个m的加密参数 看来这题的主要目的就是 看看m
  • 高德地图测距离

    不需要引入其他 高德地图测距离 getDistance lat1 lon1 lat2 lon2 var radLat1 lat1 Math PI 180 将角度换算为弧度 var radLat2 lat2 Math PI 180 将角度换算
  • Python_观察者模式

    观察者模式 又叫发布 订阅模式 定义了一种一对多的依赖关系 让多个观察者对象同时监听一个主题对象 当这个主题对象的状态发生变化时通知所有的观察者对象 让他们自动更新自己的状态 俗话说 蚂蚁搬家蛇过道 明日必有大雨到 现在我们反过来 大雨将要
  • linux查看我的所有文件夹,Linux查看所有子文件夹及文件的数量

    find命令查看 推荐 所有子目录的数量 root localhost find afish type d wc l 158 root localhost find afish type d wc l 158 root localhost
  • Jenkins自动化部署

    Jenkins自动化部署 原理 需要环境 环境搭建 linux 配置参考 环境配置 springboot项目部署配置 1 新建文件夹 2 新建maven 项目 运行脚本 创建视图 图片上传麻烦需要的的看 pdf 原理 外链图片转存失败 源站
  • 10分钟详解Spring全家桶7大知识点

    Spring框架自2002年诞生以来一直备受开发者青睐 它包括SpringMVC SpringBoot Spring Cloud Spring Cloud Dataflow等解决方案 有人亲切的称之为 Spring 全家桶 很多研发人员把s
  • 【golang】12、gin 源码解析

    文章目录 快速使用 返回响应 路由匹配 path query Multipart Urlencoded Form 解析请求 MultipartFrom MiddleWare github com gin gonic gin 是 golang
  • 盗版网课有多猖狂?原价上万,只卖5元

    燃财经 ID rancaijing 原创 作者 孟亚娜 编辑 周昶帆 金玙璠 学而思三年全套数学课程50元 送猿辅导高一数学 需要吗 新冠肺炎疫情期间 在线教育行业火爆为头部品牌打响了知名度 相关的低价盗版课也顺水推舟 再次猖獗起来 动辄上
  • Kubernetes之配置与自定义DNS服务

    本文解释如何为kubernetes集群配置及自定义DNS服务 从kubernetes1 11版本开始 coreDNS插件被包含在GA发行版中 并且被kubeadm默认安装 详情 Configuring CoreDNS and Using C

随机推荐

  • 深度学习中的Epoch,Batchsize,Iterations深刻理解

    嵌牛导读 Epoch Batchsize Iterations 这三个都是深度学习训练模型时经常遇到的概念 你一定有过这样的时刻 面对这几个词傻傻分不清楚 这三个概念究竟是什么 它们又有什么区别 嵌牛鼻子 深度学习 梯度下降 Epoch B
  • IDEA 自动补全代码快捷键设置

    IDEA 自动补全代码快捷键设置 个人喜好 一 自动补全 快速生成方法返回值 gt 原始快捷键 ctrl alt v gt alt enter file gt settings gt Keymap gt Main Menu gt Refac
  • 基于Selenium+Python的web自动化测试框架(附框架源码+项目实战)

    目录 一 什么是Selenium 二 自动化测试框架 三 自动化框架的设计和实现 四 需要改进的模块 五 总结 总结感谢每一个认真阅读我文章的人 重点 配套学习资料和视频教学 一 什么是Selenium Selenium是一个基于浏览器的自
  • Android接入三方登录——QQ

    facebook错误1 feature unavailable facebook login is currently unavailable for this app since we are updating additional de
  • 记 ReactiveWebServerFactory bean defined in the context. 导致的异常

    异常内容 APPLICATION FAILED TO START Description Web application could not be started as there was no org springframework bo
  • chatgpt赋能python:Python多行注释

    Python 多行注释 在 Python 中 我们经常需要写注释来解释代码或者用于调试 Python 的注释分为单行注释和多行注释 本文主要介绍 Python 中如何多行注释 单行注释 在 Python 中 单行注释以符号 开头 可以写在代
  • Windows的密码生成算法——NTLM算法破解

    文章目录 方法一 Python代码暴力破解 方法二 hashcat工具破解 NTLM CDABE1D16CE42A13B8A9982888F3E3BE hint 密码长度不超过5 数字和符号组成 Windows下NTLM Hash生成原理
  • mysql5.7 免安装版配置

    文章目录 my ini 安装为服务 启动服务命令 移除服务命令 修改 root 账号的密码 初始化数据 my ini 复制 my default ini 或者新建 client port 3306 default character set
  • <mirrorOf>标签用于指定哪些仓库或仓库组需要使用该镜像源

    在Maven配置镜像源时 确实会使用到mirrorOf
  • 使用内核API函数找到I2C和串口控制器发送数据

    我们一般操作I2C或者串口都是编写应用程序调用内核硬件提供的设备节点操作这些硬件的 但是在某个项目中 需要在shutdown的时候往i2c和tty发送数据 发送数据给外置的mcu mcu几秒内就会给cpu断电 所以 这个动作无法在应用层中完
  • 靠谱的车 算法

    靠谱的车 程序员小明打了一辆出租车去上班 出于职业敏感 他注意到这辆出租车的计费表有点问题 总是偏大 出租车司机解释说他不喜欢数字4 所以改装了计费表 任何数字位置遇到数字4就直接跳过 其余功能都正常 比如 23再多一块钱就变为25 39再
  • Amazon S3 REST方式获取Object

    Amazon S3 用REST方式获取文件 具体参见API http docs aws amazon com AmazonS3 latest API RESTObjectGET html 利用C 构建下面的请求 GET ObjectName
  • MSCAN:Learning Deep Context-aware Features over Body and Latent Parts for Person ReID阅读笔记

    Learning Deep Context aware Features over Body and Latent Parts for Person Re identification 作者 DangWei Li等人 CVPR 2017 1
  • DOS常用命令(从入门到精通)

    DOS命令学习 一 DOS使用常识 DOS的概况 DOS Disk Operating System 是一个使用得十分广泛的磁盘操作系统 就连眼下流行的Windows9x ME系统都是以它为基础 常见的DOS有两种 IBM公司的PC DOS
  • 朴素贝叶斯理论推导与三种常见模型

    朴素贝叶斯 Naive Bayes 是一种简单的分类算法 它的经典应用案例为人所熟知 文本分类 如垃圾邮件过滤 很多教材都从这些案例出发 本文就不重复这些内容了 而把重点放在理论推导 其实很浅显 别被 理论 吓到 三种常用模型及其编码实现
  • C++ 和 OpenCV 实现卷积神经网络并加载 Keras 训练好的参数进行预测

    C 和 OpenCV 实现卷积神经网络并加载 Keras 训练好的参数进行预测 一 背景 二 Keras 定义神经网络结构 channels first 与 channels last channels first 与 channels l
  • Sourcetree 打开闪退怎么处理

    只需要把箭头指向的SourceTree exe Url 3vynpq3lkfkc3vf35ldq2wva2cs3o2zs文件删除 如果是多个一并删除 只留一个SourceTree文件夹即可
  • WebService 与 SOAP、WSDL、UDDI

    什么是WebService Web Services 是一种基于组件的软件平台 是面向服务的Internet 应用 Web Services 是应用于Internet 的 而不是限于局域网或试验环境 这要求提出的Web Services 框
  • 微服务2-nacos 配置中心

    1什么是配置中心 在微服务架构中 当系统从一个单体应用 被拆分成分布式系统上一个个服务节点后 配置文件也必须跟着迁移 分割 这样配置就分散了 不仅如此 分散中还包含着冗余 如下图 2为什么要使用配置中心 配置中心将配置从各应用中剥离出来 对
  • Unity 游戏框架搭建 2017 (五) 简易消息机制

    什么是消息机制 23333333 让我先笑一会 为什么用消息机制 三个字 解 耦 合 我的框架中的消息机制用例 1 接收者 Receiver cs using UnityEngine namespace QFramework Example