Unity3D中的游戏对象的SendMessage方法

  当时一看SendMessage函数,瞬间感觉好高大上,但是仔细研究了一下,其实属于一种语法糖。我们完全可以用一种更加直接的方式,但是可能需要多些点儿字母:例如我们需要在另一个脚本中获得一个游戏对象goInvokeObj的Greet.cs脚本的一个Public方法 public void Greet(),我们可以在该脚本的Start()函数中使用SendMessage()按如下方式写:  goInvokeObj.SendMessage("Greet");这样我们就不需要写明哪个脚本了。但是这样感觉思路上多转了一圈,看看用简单粗暴好理解的方式实现吧。 在Start函数中变为 goInvokeObj.GetComponent<Greet>().Greet()。就多了一句获得Greet.cs脚本的语句,这样我们还多了一个该函数在哪个脚本的信息,这是SendMessage函数所不具备的功能呀。

  讲到这儿,我就有一个疑问了,如果一个游戏对象goInvokeObj身上挂了两个脚本GreetChinese.cs 和 GreetEnglish.cs,并且恰好这两个脚本都已共同的public方法 public void Greet(),那我们调用goInvokeObj.SendMessage("Greet")会得到怎样的结果呢? 刚刚做完实验,发现结果是这个样子的:SendMessage函数把goInvokeObj身上挂了两个脚本GreetChinese.cs 和 GreetEnglish.cs的Greet()函数都执行了一遍。或许有这么一种情况,当我们要求该游戏对象的不同脚本的某个函数都要执行一遍的话,用SendMessage还是非常棒的。据说,SendMessage数据传值技术是Unity官方推荐的方式,所以,简单粗暴的方式还是不用为好了。刚刚试了一下SendMessage函数,发现调用SendMessage的游戏对象的被调用的函数不一定必须public修饰的函数,例如下面的代码中的Greet(),为private也是可以的,也可以将字符串传到goInvokeObj里面的Greet函数中的,这功能有点儿逆天呀。

  说到数据传值,就是将我们需要的变量传到SendMessage中的函数中去,在这里也就是Greet()函数啦。但是SendMessage中使用字符串标识函数名,换言之,只要函数名相同就行,我做过这样一个实验,我用了goInvokeObj.SendMessage("Greet","LiMing"),但是我的不带参数的Greet()函数也会被执行到,这或许在某些方面还是一个坑吧。只根据函数名而不是函数签名(函数名,参数类型,参数个数)的方式,是我现在接受不了的。如果换成GreetChinese(int age)函数,则系统会很负责任的告诉我们。

      MissingMethodException: The best match for method Greet has some invalid parameter.

  好了,上代码。代码中的goInvokeObj就是绑定了GreetEnglish.cs和GreetChinese.cs脚本的对象。上面的异常就是Greetchinese脚本中的Greet函数参数与SendMessage中指定的参数不匹配导致的。

  

 1 using UnityEngine;
 2 using System.Collections;
 3 //在该脚本中进行SendMessage的测试
 4 public class TestSendMessage : MonoBehaviour {
 5     public GameObject goInvokeObj;
 6     // Use this for initialization
 7     void Start () {
 8         goInvokeObj.SendMessage ("Greet","shengming",SendMessageOptions.RequireReceiver);
 9     }
10 
11 }
12 
13 
14 using UnityEngine;
15 using System.Collections;
16 
17 public class GreetEnglish : MonoBehaviour {
18 
19     public void Greet(string name)
20     {
21         print ("hello" + name);
22     }
23 }
24 
25 
26 using UnityEngine;
27 using System.Collections;
28 
29 public class GreetChinese : MonoBehaviour {
30 
31      public void Greet(int name)
32     {
33         print ("你好"+name);
34     }
35 }

 

posted @ 2015-05-03 12:19  kylinxue  阅读(11862)  评论(0编辑  收藏  举报