协程的流程:
Unity的协程按我自己的理解就是将一段代码延迟一段时间后再去执行,它的执行顺序是先启动协程,然后执行协程内的代码一直到yield语句,然后继续执行主程的代码,直到yield条件满足后程序会再次跳到yield之后的语句继续执行协程内的语句,知道协程内的语句执行完,或者又遇到yield语句,就继续上述流程。(具体可以去百度协程,这里只是大概讲一下)
无参数的协程的启用与禁止:
协程的 启动方式一般有两种,一个是直接用函数名的字符串,另一个就是直接调用函数。这一章我先讲讲用函数名启动的协程。
函数调用的启动与关闭:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CorTest : MonoBehaviour {
private void Start()
{
StartCoroutine(Normal());
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.J))
{
Debug.Log("【CorTest】Update 按下j键");
StopCoroutine(Normal());
}
}
IEnumerator Normal()
{
int f = 0;
while (true)
{
yield return new WaitForSeconds(1f);
f++;
Debug.Log("【CorTest】Normal 运行一次协程,f值:" + f);
}
}
}
这一段代码就是每一秒打印一次f, 当我按下J的时候就会去停止函数。各位可以猜测一下结果下面我 放一下测试的结果:
可以看到, 结果并没有被停止,这说明用函数的方式去停止 协程是不可取的,那么用函数名停止呢?将停止代码改为下方代码:
接下来的测试结果各位也可以猜一猜:
还是可以发现,结果并没有停止,这说明,用函数启动的协程其实是并不能通过名字以及函数去直接停止的,这个时候的停止方式除了StopAllCoroutines()函数以外,还有一种方式,用变量Coroutine来存储协程信息,并以此来停止协程,这里 就不再放测试结果了,根据测试 是可行的,将如下两处代码修改一下即可:
既然无参数都只能用StopAllCoroutines和变量Coroutine来停止,那么可以猜测,带参数的估计也就只能用这两种方式来停止了,接下来测试一下,修改如下两处代码,我们还是通过变量来停协程:
这里我们打印出的是valueName的值f,测试结果如下:
可以看到结果是可以被停止的,这里各位也可以去测试一下用名字和函数停止的方式,反正我测试的结果是无法停止。。。
那么接下来测试一下传入委托会怎么样,这里用Action来测试一下,不懂lamda表达式的请自行百度,这里只会解释一下这段代码是干什么的,还是修改如下 两处代码:
这 样修改就相当于把原来的f++和打印操作交给了action来处理,这两个操作 将会在action里面去执行。表达式里的x就相当于函数的参数(有两个变量那肯定是一一对应了), 大括号里面是函数体。结果如下:
为什么打印的值都是1呢???这是因为按照 文章最开是我给出的协程流程的解释来说,在满足yield语句后,程序将会 向下继续执行,也就是去执行action(f),然而由于每次执行到这里的时候 传入的f值都没有改变,所以每次的结果都是1,想要做到原本的效果,要么将f作为ref或out传递,要么就将x值返回给f。
总结:
通过函数启动的协程,无法通过StopCoroutine("FuncName")和StopCoroutine(Func())的形式停止(不管有没有参数),只能通过变量Coroutine的形式才能停止(StopAll就不说了,肯定可以),而启动的协程不管带有多少参数,参数的形式是怎样的,都可以通过此方法来停止。