异步函数:调用 (Invoke)
在一个方法执行时调用另一个方法。
而被调用的方法或者其中的某些语句不是立刻执行,而是过一段时间后才执行。
MonoBehavior 提供了两种异步方法:
调用:(Invoke)
协程:(协同 ,协同程序,Coroutine)
Invoke 代码测试:
public class InvokeDemo : MonoBehaviour {
void Start () {
Invoke("Show",2f); //游戏运行2s后调用一次Show方法
InvokeRepeating("Show", 3f, 2f); //游戏运行3s后调用第一次,以后每隔2s调用一次
Debug.Log(IsInvoking("Show")); //此时打印true 检测此MonoBehaviour是否有调用在等候
CancelInvoke("Show"); //停止此脚本上的Invoke,没有参数就是清除所有的Invoke,有参数清除指定参数,执行后上面两种方法都会停止。
Debug.Log(IsInvoking("Show")); //此时为false,表示上面的停止方法起作用了
}
void Show()
{
//创建了一个标准立方体
GameObject.CreatePrimitive(PrimitiveType.Cube);
}
}
注:Invoke是不能接受有参数的方法的;
Invoke是受Time.timeScale的影响,所以当 Time.timeScale = 0;的时候Invoke是无效的。因为它根本调用不到,,,无论Invoke可所对应的物体或者组件状态改为未激活(active = false;enable = false;),也无法停止Invoke。除非它所依附的gameObject被销毁(Destroy)。
协程(coroutine)
主程序运行的同时,开启另一段逻辑处理,来协同当前的程序一同执行处理,(协程并不是线程)
Unity中的线程:
所需要的函数类型需要一个返回的迭代器(IEnumerator)需要函数中有挂起yield return
一个协同程序在执行过程中,可以在任意位置使用yield return的返回值控制何时恢复协同向下执行
yield 是一种特殊类型的return(返回)语句,他可以确保函数下一次被执行时,不是从头开始,而是从yield 语句处开始。
public class Coroutine : MonoBehaviour {
void Start () {
StartCoroutine("Show"); //使用字符串方式,开启协程
StartCoroutine("Show", 5); //第二个参数是Show()方法的参数 最多可传一个参数
StartCoroutine(Show()); //使用IEnumerator类型参数 进行协程调用
StartCoroutine(Show(10,2));//此方法可以传无限参数
}
// Update is called once per frame
void Update () {
StartCoroutine("Show");
StopCoroutine("Show"); //遇到yield return就不再执行 只能停止字符串传参得函数
StopCoroutine("Show"); //遇到yield return就不再执行
//StopCoroutine(Show()); //目前测试此方法无效
StopAllCoroutines(); //此方法可以停止两种协程
}
IEnumerator Show()
{
print("befor");
yield return new WaitForSeconds(2f); //2s后继续执行协程
print("after");
yield return new WaitForSeconds(1f);//1s后继续执行协程
print("final");
}
IEnumerator Show(int i)
{
print("befor "+ i);
yield return null;
}
IEnumerator Show(int i ,int j)
{
print(j + i);
yield return null;
}
}
对比:
Invoke 是在开启的时候给一个时间告诉几秒后调用,而coroutine是直接调用方法中去处理等待时间,Coroutine在处理上时间更灵活
Invoke将物体激活关闭们不会停止调用,Coroutine将物体激活关闭,将不能调用
Invoke不支持传参数 Coroutine支持
SendMessage 发送消息
GameObject.SendmessageUpwards // 向上发送消息 向其物体的所有父级及本身
GameObject.BroadcastMessage // 广播消息,,向其物体的所有子级及本身发消息
GameObject.SentMessage //发送消息 ,
SendMessageOptions //发送消息选项
SendMessage是一个非常强大的消息推送机制
目的为: 只要调用了此方法,同时持有某个类的引用.则可以向这个类本身,或者其子类,或其父类传递消息,而达到执行指定的某个函数方法
这个过程非常方便的实现了某个引用,从而大大简化了开发过程中的复杂程度
GameObject.SendMessage(string methodName)会搜索这个GameObject上所有的Component中所有叫做methodName的方法,并调用这些个方法
三种方法使用方式完全一样,只是使用用途,或者说使用对象有所不同
使用的方法利用反射的机制来检索所有游戏对象身上是否存在发送消息的目标,所以很占用资源,空间 开发中并不常用,,,方法虽然很强大,但执行效率并不高
注:此函数是跨语言的,例如JavaScript可以调用C#中的函数,,还有就是目标本身所有同名方法都会被执行一次(即如果Demo1,Demo2中有同名函数,就各执行一次)