1、首先要明确一点Unity是支持多线程的,只是新开线程无法访问Unity相关对象的内容。
******Unity中的多线程 要记住关闭***********
Unity中去使用:
如果说,我们一开始在Start内创建一个多线程,那么我们无法在start外得到以及销毁它。
因此我们大部分时候在类中定义它。将线程作为一个成员变量。
线程内传入的是一个委托。(第二种重载 为无参无返回的委托,也就是说需要传一个无参无返回函数)
完美运行:证明在Unity中我们是可以使用多线程的。
我们在线程中写一个死循环来计时,让这个线程一直跑。
运行:确实如我们所想一直在运行。
我们关闭Unity运行:
发现这个线程还在不停的运行!
为什么?因为Unity是一个编辑器的存在,开的线程和Unity共生了。Unity本质上也是一个软件,只要软件没有关或者脚本没有改变,这个线程就会一直运行。
因此,******Unity中的多线程 要记住关闭***********
至于说为什么在Unity中新开的线程无法访问Unity相关对象:
我们在新开线程中改变物体的position:
运行:发现报错了。transform需要在主线程中去运行。
因此,Unity虽然支持多线程,但是新线程无法访问Unity内容。
我们甚至只是想在新线程中去打印Unity的内容都是不行的。不谈改变Unity,打印都不行!
不能访问
新开的线程虽然不能访问Unity,但是多线程可以进行一些复杂的逻辑计算:例如A*算法、网格计算,复杂的计算可能会卡住主线程,因此我们用副线程去计算。算好了,主线程去用。
声明一个变量作为一个公共内存容器,一个线程放,一个线程取。
在多线程中放入队列中。
在Unity主线程中,去判断、获得队列中的内容。
通过中间商来进行数据的交互,很重要。
协同程序简称协程 它是“假”的多线程,它不是多线程 他的本质是一个迭代器!
新线程是和主线程并行执行,就像两条平行线一样。
协程和主线程则是,依附在主线程上。
当一个函数被协程运行时,它可以分成n个部分。它不需要在一个主线程的流程中执行完毕。Unity的主线程也是一个无限循环的线程。协程执行函数的1部分,根据返回的内容决定是否继续向下执行。如果不执行,这个协程就会被挂起。分时分步,执行的时间和执行的步骤都是我们可以控制的。
直到函数被执行完毕,协程结束。
在MyCoroutine中,先输出i, 然后返回的条件为:要等待5秒钟,5秒之后再输出str
执行后没有反应:
常用开启的方式:StartCoroutine
第一种重载:直接写协程函数。
第二种重载:直接传字符串(这种的不常用)
第三种重载:字符串+参数(也不常用)
最常用的方法:
另一种常用方法:本质上是一样的。
运行:协程开启
再协程函数中,函数被yield return分成了几部分。一个协程函数可以有多个yield return。
只要碰到 yield return 会根据条件来执行后面的程序。(例如:等5秒、等1秒)
一个协程函数可以执行多次:
StartCoroutine返回的是Coroutine,是一个协程对象。我们可以将它存起来。
运行:发现输出了三个1,两个123。三个协程都输出了1,当在等待5秒的过程中,c1被关闭了。只有c2,c3输出了123.
协程中写一个死循环,一定条件下对主线程没有太大影响。
无论数字是多少或者是null,都表示下一帧执行下面语句。
在Update和LateUpdate之间执行。
在start()函数中执行了MyCoroutine()输出了i。等待5秒后输出str,那么这个输出是什么时候执行呢?在Update和LateUpdate之间执行。
FixUpdate和碰撞检测相关函数之后执行。
在LateUpdate之后的渲染相关处理完毕后执行。
yield break;
yield return之后的语句不会执行。