首页 > Unity3D频道 > 【Unity3D研究院之游戏开发】 > Unity3D研究院之通过C#使用Advanced CSharp Messenger(五十)
2013
03-25

Unity3D研究院之通过C#使用Advanced CSharp Messenger(五十)

Advanced CSharp Messenger 属于C#事件的一种。 维基百科中由详细的说明http://wiki.unity3d.com/index.php?title=Advanced_CSharp_Messenger 上周的一天刚巧有朋友问到我这一块的知识,那么我研究出来将它贴在博客中,帮助了他也帮助我自己!哇咔咔。

Advanced CSharp Messenger的特点可以将游戏对象做为参数发送。到底Advanced CSharp Messenger有什么用呢?先创建一个立方体对象,然后把Script脚本绑定在这个对象中。脚本中有一个方法叫DoSomething()。写一段简单的代码,通常我们在调用方法的时候需要这样来写。

 

代码比较简单,我就不注释了。 原理就是先获取游戏对象,接着获取脚本组件对象,最后通过脚本组件对象去调用对应脚本中的方法,这样的调用方法我们称之为直接调用。

这个例子中我只调用了一个对象的方法,如果说有成千上万个对象,那么这样调用是不是感觉自己的代码非常的丑?因为你需要一个一个的获取对象然后获取脚本组件然后在调用方法。。。。。 (想想都恐怖!!)

下面我们在用Advanced CSharp Messenger来实现事件的调用。按照维基百科中首先把Message.cs 和Callback.cs拷贝在你的工程中。

CallBack.cs

 Message.cs

 然后就可以开始使用了,Messager.Broadcast()这样就好比我们发送了一条广播。

 在需要这条广播的类中来接受它,同样是刚刚说的Script类。接受广播的标志是 Messager.AddListener()参数1表示广播的名称,参数2表示广播所调用的方法。

 这样一来,只要发送名称为”Send”的方法,就可以在别的类中接收它了。

我们在说说如何通过广播来传递参数,这也是那天那个哥们主要问我的问题。(其实是维基百科上写的不是特别特别的清楚,那哥们误解了)在Callback中可以看出参数最多可以是三个,参数的类型是任意类型,也就是说我们不仅能传递 int float bool 还能传递gameObject类型。

如下所示,发送广播的时候传递了两个参数,参数1是一个游戏对象,参数2是一个int数值。

 然后是接受的地方 参数用<>存在一起。游戏对象也可以完美的传递。

 

如果传递一个参数<T>

两个参数<T,T>

三个参数<T,T,T>   

怎么样使用起来还是挺简单的吧?

我觉得项目中最好不要大量的使用代理事件这类的方法(根据需求而定),虽然可以让你的代码非常的简洁,但是它的效率不高大概比直接调用慢5-倍左右吧,就好比美好的东西一定都有瑕疵一样。 还记得Unity自身也提供了一种发送消息的方法吗?,用过的都知道效率也非常低下,虽然我们看不到它具体实现的源码是如何实现的,但是我觉得原理可能也是这样的。 欢迎和大家一起讨论与学习。

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

Unity3D研究院之通过C#使用Advanced CSharp Messenger(五十)》有 39 条评论

  1. 狗蛋 说:

    通俗易懂,解决了我半个月都没看懂的事,给你打钱了么么哒

  2. why 说:

    c#内置的事件系统会明确要求消息的目标,而且目标也同样要求知道消息的精确来源,在消息有广播需求时就会捉襟见肘了,这时候可以使用第三方的advanced c# messenger类(源码来自wiki库贡献,网上任意搜),它具有在消息传递沟通时非常好的解耦作用,对于传递消息时源任意,目标任意的情景比较适配。

  3. caochao 说:

    这就是c#中的委托和事件,类似于c中函数指针~,效率不好会慢的~

  4. Andy3515 说:

    MO哥,提个小建议,能给你的网站的代码部分加上一键复制代码的功能不,这样大家用起来会更方便一些。嘿嘿、、 Unity3D研究院之通过C#使用Advanced CSharp Messenger(五十) - 雨松MOMO程序研究院 - 1

  5. 斗胆大叔 说:

    MOMO这个和代理事件的效率比起来呢?也要慢吗?

  6. 洪峤 说:

    可以把要传的参数封装成一个类,这样只需定义一个参数的委托。这样可以吗?

  7. 感觉用上去特别像 信号槽的 思想

  8. 张锟utans 说:

    我也经常用到这个,但是不会把AddListener 放到Awake()中去监听,一般会放在OnEnable()中去负责监听,最后在OnDisable()中使用RemoveListener()去除掉监听者。

  9. SendMessage 是基于Reflection的 所以很慢

  10. chungchunyin 说:

    MOMO老师,这个,新手完全不清楚它用法啊….callback和Message到底合在一条脚本里?还是分开的?还有,脚本是挂在哪里的?是场景新建一个空物体吗,然后两条挂上去吗?

  11. 寒鸦 说:

    嘿,我就是问你的那个人,这是Advanced CSharp Messenger的用法:http://www.cnblogs.com/HelloUnity/archive/2013/06/18/AdvancedCSharpMessenger.html目前项目正在轰轰烈烈的使用中…

  12. 欧宇龙 说:

    我倒觉得,SendMessage不会那么低。毕竟这个方法的执行是微秒级别的。就算是100倍的差异用户也几乎不会有任何感知。如果能够吧执行次数控制在 平均每秒10次内,就能用。

  13. muqian3288 说:

    请教一下,这个慢5倍是怎么得出的?我不太会测

  14. 十一郎 说:

    方法的执行效率也是我最关注的,看来这种方法也是只能用在特殊场合了.

  15. 黄杰 说:

    嗯,厉害厉害~

  16. hjboo 说:

    都说委托事件快于unity的sendmessager,对此我也深信不疑,但sendmessage到底是基于何种机制呢?NGUI的很多事件消息的传送就直接用的是sendmessage,运行的速度感觉不到有多慢,挺纠结的,后来直接干脆两者混合着用,呵呵。

  17. Gamars 说:

    这方法挺好的,只是效率方面会怎样呢?

留下一个回复

你的email不会被公开。