什么是消息机制?

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

更多内容

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

  1. Unity 游戏框架搭建 (四) 简易有限状态机

    为什么用有限状态机?   之前做过一款跑酷游戏,跑酷角色有很多状态:跑.跳.二段跳.死亡等等.一开始是使用if/switch来切换状态,但是每次角色添加一个状态(提前没规划好),所有状态处理相关的代码 ...

  2. Unity 游戏框架搭建 (十一) 简易AssetBundle打包工具(一)

    最近在看Unity官方的AssetBundle(以下简称AB)的教程,也照着做了一遍,不过做出来的AssetBundleManager的API设计得有些不太习惯.目前想到了一个可行的解决方案.AB相关 ...

  3. Unity 游戏框架搭建 (十) QFramework v0.0.2小结

    从框架搭建系列的第一篇文章开始到现在有四个多月时间了,这段时间对自己来说有很多的收获,好多小伙伴和前辈不管是在评论区还是私下里给出的建议非常有参考性,在此先谢过各位. 说到是一篇小节,先列出框架的概要 ...

  4. Unity 游戏框架搭建 2018 (一) 架构、框架与 QFramework 简介

    约定 还记得上版本的第二十四篇的约定嘛?现在出来履行啦~ 为什么要重制? 之前写的专栏都是按照心情写的,在最初的时候笔者什么都不懂,而且文章的发布是按照很随性的一个顺序.结果就是说,大家都看完了,都还 ...

  5. Unity 游戏框架搭建 (十六) v0.0.1 架构调整

    背景: 前段时间用Xamarin.OSX开发一些工具,遇到了两个问题. QFramework的大部分的类耦合了Unity的API,这样导致不能在其他CLR平台使用QFramework. QFramew ...

  6. Unity 游戏框架搭建 (十三) 无需继承的单例的模板

    之前的文章中介绍的Unity 游戏框架搭建 (二) 单例的模板和Unity 游戏框架搭建 (三) MonoBehaviour单例的模板有一些问题. 存在的问题: 只要继承了单例的模板就无法再继承其他的 ...

  7. Unity 游戏框架搭建 2019 (五十、五十一) 消息机制小结&MonoBehaviourSimplify 是框架?

    我们花了 5 篇文章学习了消息机制的方方面面.并且完成了一个简易消息机制,之后集成到了我们的 MonoBehaviourSimplify 里. 现在 MonoBehaviourSimplify 有一点 ...

  8. Unity 游戏框架搭建 2019 (四十六) 简易消息机制 & 集成到 MonoBehaviourSimplify 里

    在上一篇,我们接触了单例,使用单例解决了我们脚本之间访问的问题. 脚本之间访问其实有更好的方式. 我们先分下脚本访问脚本的几种形式. 第一种,A GameObject 是 B GameObject 的 ...

  9. 凉鞋:我所理解的框架 【Unity 游戏框架搭建】

    前言 架构和框架这些概念听起来很遥远,让很多初学者不明觉厉.会产生"等自己技术牛逼了再去做架构或者搭建框架"这样的想法.在这里笔者可以很肯定地告诉大家,初学者是完全可以去做这些事情 ...

随机推荐

  1. UGUI ScrollRect 性能优化

    测试环境 操作系统:Windows8.1 开发工具:Unity5.5.2 1.问题描述,在实际开发过程中经常会使用ScrollRect实现滚动列表,当初次加载数据比较多的情形时,Unity3D会出现比 ...

  2. 用kotlin方式打开《第一行代码:Android》之开发酷欧天气(1)

    参考:<第一行代码:Android>第2版--郭霖 注1:本文为原创,例子可参考郭前辈著作:<第一行代码:Android>第2版 注2:本文不赘述android开发的基本理论, ...

  3. JVM与对象初始化

    一个对象从无到有的过程 A a = new A() 1.JVM遇到new指令就会去堆内存分配一块内存空间,内存的大小在编译期间就可以确定 2.接着调用A的构造函数,这里构造的时候会沿着继承树逆流而上, ...

  4. chrome的断点调试

    DOM节点变化时触发断点具体触发条件可分3种情况:子节点有变化.节点的属性发生变化或这个节点被删除.可以快速找到对应的事件处理函数. 条件断点 写一个表达式,表达式为 true 时才触发该断点. 在D ...

  5. Spring MVC和Struts2的比较

    Spring MVC PK Struts2 我们用struts2时采用的传统的配置文件的方式,并没有使用传说中的0配置.spring3 mvc可以认为已经100%零配置了(除了配置spring mvc ...

  6. 007---Hibernate基本映射标签和属性介绍

    一.映射文件的基本结构举例: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-// ...

  7. [原创]首次SDN比赛的记录-部分

    SDN大赛环境搭建和第一大题实现 由于物理设备不足的原因,故用虚拟机实现Floodlight控制器,openvswitch(以下简称:OVS)和mininet各种要用到的SDN环境的搭建.下面将给出它 ...

  8. VR问题无关方向,VR全景为您领航,全景智慧城市已势不可当

    2016年,VR绝对是互联网科技圈的一个高频词. 在这一年里,Magic Leap获得阿里领投的近8亿美元的融资,VR公司的商业价值得到认可.Oculus Rift和HTC Vive的VR产品正式发货 ...

  9. Nginx上部署HTTPS

    Nginx上部署HTTPS依赖OpenSSL库和包含文件,即须先安装好libssl-dev,且ln -s /usr/lib/x86_64-linux-gnu/libssl.so  /usr/lib/, ...

  10. [Lucene]-Lucene基本概述以及简单实例

    一.Lucene基本介绍: 基本信息:Lucene 是 Apache 软件基金会的一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎.Luc ...