【声明】作者初学unity只是想记录学习笔记,很多地方可能解释不到位,敬请批评指正!
什么是协程
我第一次听到协程的概念是缘于需要做一个场景转换,场景转换的动画播放需要一定的时间,因此必须等待这段时间之后调用加载场景的函数,这样才能够达到预期效果,但是我并不希望程序除此之外的功能受这个等待时间影响。由此可见,形象地理解协程的作用就是让程序的一部分“独立”出来。
如果了解过多线程的话,你可能觉得这个“协程”的作用好像和多线程类似,即在不影响主线程的情况下,并发地进行另一个线程。但事实上unity的协程与线程是完全不同的两个概念。
线程是并发的,可以同时有多个线程运行。线程的执行顺序取决于操作系统的线程调度器,因此它们可能以任何顺序执行,存在复杂性。
而协程是主线程的一部分,与主线程同步更新,因此它们不会开启新的线程,而是利用主线程的空闲时间来执行,这使得协程成为一种轻量级的异步编程方式。
在传统的同步编程模型中,一旦一个函数开始执行,它就会一直运行到结束,除非遇到某种形式的阻塞(例如I/O操作、等待用户输入等)。但是协程很好的解决了这个问题:在协程没有暂停之前,其和主线程共享相同的执行环境顺序执行,与普通函数无异;但协程具有暂停的功能,其暂停并不会阻塞主线程,具有相对独立性。此外协程还具有一个优点,unity会不断检查是否有暂停的协程存在,并记录当前中断点的执行位置,在暂停结束后能够接着暂停之前的程序继续运行。这也就是为什么在需要等待一段时间执行的功能需要用协程实现的原因。总的来说,协程不同于线程那样复杂,但能很好地解决异步编程的问题。
协程的语法
Unity协程引入了迭代器(IEnumerator)和yield关键字。在协程函数中,yield return语句被用来暂停协程的执行。
首先,我们需要一个函数(StartCoroutine)来激活一个协程;其次,激活的协程会进入迭代器;最后,在迭代器中编写想要的程序,在适当时候使用yield return语句执行暂停操作。具体代码框架如下:
public void Stop()
{
//当主循环内调用Stop()函数后开启协程
StartCoroutine(IE());
//函数原型 StartCoroutine(IEnumerator IE);
}
IEnumerator IE()
//这里的IE可以有参数,取决于编程需要,与普通函数一样,只是类型是IE
{
//编写代码... 这些代码在进入IE后会顺序执行直到碰到yield return
yield return new WaitForSeconds(float Time);
//WaitForSeconds是一个结构体,它封装了一个等待特定秒数的行为
//new WaitForSeconds(time)实际上是创建了一个等time秒的实例
//暂停Time秒后继续执行以下内容
//编写代码...
//若函数执行结束没有遇到暂停语句,自动结束协程
}
实例演示
这里以一个随机方向的小球发射器为例,每5秒发射一个球。
using System.Collections;
using UnityEngine;
public class BallLauncher : MonoBehaviour
{
public GameObject ball; // 小球
public float launchInterval = 5.0f; // 发射间隔
public float launchForce = 10.0f; // 发射力
private void Start()
{
// 开始发射小球的协程
StartCoroutine(LaunchBalls());
}
private IEnumerator LaunchBalls()
{
while (true)
{
// 等待指定的发射间隔
yield return new WaitForSeconds(launchInterval);
// 创建一个新的小球实例
GameObject ballInstance = Instantiate(ball, transform.position, Quaternion.identity);
// 获取小球的刚体组件
Rigidbody rb = ballInstance.GetComponent<Rigidbody>();
if (rb != null)
{
// 生成一个随机的方向向量
Vector3 randomDirection = Random.onUnitSphere;
// 应用发射力
rb.velocity = randomDirection * launchForce;
}
Destroy(ballInstance, 10.0f); // 10秒后销毁
}
}
}
3823

被折叠的 条评论
为什么被折叠?



