[Unity 代码写法整理]消息机制(一)

消息机制的作用:

1.广播,当需要通知给多个对象或者模块的时候,类似于安卓的广播一样。比如一个即时战略游戏,里面有很多单位,当接收到游戏结束的消息时,所有的兵种Idle静止。

2.跨线程调用,Unity只能在UI线程调用UnityEngine相关函数(少部分除外),当跨线程调用时,很多时候都需要UI给用户一个反馈,比如使用IO操作读取文件、连接数据库读取数据、Socket的Accept和Receive、网络请求回调(指的是HttpWebRequest而不是www),可以写一个MessageQueue让一个脚本在Update中轮询,当非主线程得到回调时,向MessageQueue中添加消息,Update处理消息时即可回归主线程。

3.解耦,这也是我认为消息机制最主要的用法。用于界面和逻辑代码的分离,对于一个UI界面,或者是玩家控制的人物,他们的关注点应该只是如何显示得更美观,如何响应玩家的输入。比如一个背包按钮被点击,这个脚本上,应该只是把背包界面显示出来,并向背包相关逻辑发送个消息。背包的逻辑模块发送网络请求或者怎么样与我无关,我关注的只是当我收到背包物品列表这个消息之后怎么处理,或者把处理函数作为一个委托回调加入到背包被点击时的消息体里。这个好处有很多,比如我把界面的脚本移植到别的游戏里去使用,不会报错,因为贯穿UI界面和逻辑的只有消息,而并没有对背包逻辑模块的引用。

==============================

消息机制的组成(队列消息):

1.消息体,一般写作为抽象类AbstractMessage,或者抽象接口IMessage,或者基类BaseMessage。

2.消息队列,用于存放消息体,一般用队列结构,比如Queue<BaseMessage>,也有把Queue封装至一个类里面的,比如写个MessageQueue类。

3.Update函数,在每一帧扫描消息队列,当有消息发送至消息时,做响应的处理。

4.委托或者接口Handler,用于存放当消息发出时的响应函数,当然也可以直接把它放在消息体中。

5.消息字典/消息列表,也就是Dictionary或者List接口,一般字典的话,Key一般是消息体,Value一般是委托或者接口列表,类似于Dictionary<BaseMessage,List<Handler>>,消息列表的话,一般都是消息体中包含Handler,类似于List<BaseMessage>。当然还可以这样写,消息体中一般都会有一个string或者enum甚至是int、short等作为消息的名称,把这个作为key,value是消息体列表,或者Handler列表,类似于Dictionary<string,List<Handler>>和Dictionary<string,List<BaseMessage>>,反正都差不多,喜欢用哪种就哪种,开心就好。

6.消息中心,MessageCenter,一般是个单例类,提供注册事件,注销事件,Update函数、消息队列、消息字典/列表所在的类,整个消息机制的核心。

 

对于第一种队列消息机制,和安卓的消息机制超级类似,可以说照搬照抄。Message,MessageQueue,Looper,Handler可以对号入座... 他的优点我觉得最重要的是可以跨线程,当你在子线程中想要调用主线程才能调用的函数时,最好的办法就是轮询。也就是Update函数的作用。缺点也同样明显,也就是消息的处理时机并没有确定性,就跟Unity的生命周期函数一样,调用只能确定先后(甚至有些函数都分不清先后,好吧这是吐槽),不能确定时机。所以有很多人都会建议不要过分的依赖Unity生命周期函数,要有自己的类去管理。

==============================

消息机制的组成(即时消息):

1.消息体,同上。

2.委托或者接口Handler,同上。

3.消息字典/消息列表,同上

4.消息中心,MessageCenter,同上。

 

对于第二种即时消息机制,少了Update和MessageQueue,其最大的作用是在解耦上,工作机制说白了就是,发送消息时直接到消息字典和消息列表中去查找,然后调用。所以实时性很高,调用时机也很明确,就是发送消息那一行。缺点跟第一种相对,也就是不能跨线程。因为我所认为的耦合就是直接引用和直接调用所引发的强耦合。当使用消息机制贯穿整个代码后,调用都变成了"辗转"的调用,我的UI需要显示等级,第一种办法是直接调用等级逻辑里面的函数,去查询数据库,或者查询网络接口,再显示到我的面板里。那这个UI会很心累,因为他需要知道的东西太多。如果我把需要得到等级的消息给消息中心,那我只需要关心什么时候显示等级,和怎么样显示等级,然而这正是一个UI应该做的事情。有一天,我觉得这个界面很好看,想换汤不换药的搬到另一个游戏上去,或者我觉得逻辑不错,把界面换一下(当然这两种方式都比较欠揍,现在那些成天拉大明星做广告的辣鸡游戏都是这种套路!)。只要消息中心存在,那我想怎么换怎么换,甚至代码在缺少UI或者逻辑的时候不会报一个错。

==============================

两种消息的使用时机:

对实时性要求并不是很严格的东西(比如UI),用第一种

需要在其他线程调用UI线程的,用第一种

与业务逻辑关系比较密切的,实时性要求较高的,用第二种。

==============================

以上都是个人的想法,有出入的可以评论...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值