当时一看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 }