Unity2D开发入门-协程

2023-07-24 15:43:41 浏览数 (1)

前言

在Unity中,协程(Coroutine)是一种特殊的函数,可以在程序的执行过程中暂停和恢复执行。

协程通常用于处理时间相关的任务,例如延迟执行、动画序列等。

启动协程

要在Unity中使用协程,可以按照以下步骤进行操作:

创建一个带有返回类型为IEnumerator的函数,并将其标记为协程。例如:

代码语言:javascript复制
private IEnumerator MyCoroutine()
{
    // 协程的执行逻辑
    yield return null; // 暂停执行一帧
    // 继续执行逻辑
    yield return new WaitForSeconds(2.0f); // 暂停执行2秒钟
    // 继续执行逻辑
}

在需要启动协程的地方,使用StartCoroutine方法来启动协程。例如,在Start函数中启动协程:

代码语言:javascript复制
void Start()
{
    StartCoroutine(MyCoroutine());
}

暂停协程

在协程中使用yield语句来控制执行流程。yield return语句用于暂停执行,并在指定条件满足时恢复执行。

常用的yield语句包括:

  • yield return null;:暂停执行一帧,然后继续执行下一帧。
  • yield return new WaitForSeconds(delay);:暂停执行一段时间(以秒为单位),然后继续执行。
  • yield return new WaitForFixedUpdate();:暂停执行直到下一个固定更新帧。
  • yield return new WaitForEndOfFrame();:暂停执行直到当前帧渲染完毕。
  1. 在协程中可以使用循环、条件语句等控制流程,实现复杂的逻辑。

注意事项:

  • 协程只能在MonoBehaviour的派生类中使用。
  • 协程可以被中断和停止。可以使用StopCoroutine方法停止指定的协程,或者使用StopAllCoroutines方法停止当前对象上的所有协程。

示例

在规定时间内移动到某个位置

代码语言:javascript复制
private IEnumerator MoveObject
(
    Transform objectToMove,
    Vector3 endPosition,
    float duration
)
{
    var startTime = Time.time;
    var elapsedTime = 0f;

    while (elapsedTime < duration)
    {
        elapsedTime = Time.time - startTime;
        var t = Mathf.Clamp01(elapsedTime / duration);
        objectToMove.position = Vector3.Lerp
        (
            objectToMove.position,
            endPosition,
            t
        );
        yield return null;
    }

    objectToMove.position = endPosition;
}

其中

Vector3.Lerp 是 Unity 引擎中的一个函数,用于在两个向量之间进行线性插值。它的作用是在两个向量之间按照一定比例插值生成一个新的向量。

具体来说,Vector3.Lerp 的函数签名如下:

代码语言:javascript复制
public static Vector3 Lerp(Vector3 a, Vector3 b, float t);

其中,参数 a 表示起始向量,参数 b 表示目标向量,参数 t 表示插值因子(取值范围为[0, 1])。

Vector3.Lerp 的返回值是一个新的向量,通过对起始向量和目标向量进行插值计算得到。

也就是返回

起点和终点练成一条线后比例从0到1中的点。

匀速向某个位置移动

起点到终点的向量

代码语言:javascript复制
Vector3 direction = (endPoint - startPoint).normalized;

这样,direction 就是起点到终点的单位向量。

代码语言:javascript复制
private IEnumerator MoveObject
(
    Transform objectToMove,
    Vector3 endPoint,
    float duration,
    float mspeed
)
{
    var startTime = Time.time;
    var elapsedTime = 0f;
    while (elapsedTime < duration)
    {
        elapsedTime = Time.time - startTime;
        var startPoint = objectToMove.position;
        var direction = (endPoint - startPoint).normalized;
        startPoint  = direction * mspeed * Time.deltaTime;
        objectToMove.position = startPoint;
        yield return null;
    }
}

使用施加力实现

代码语言:javascript复制
private IEnumerator ShootCoroutine(Rigidbody2D body, Vector2 v)
{
    int frame = 0;
    while (frame <= 60)
    {
        body.AddForce(v * speed * Time.deltaTime);
        // 等待下一帧
        yield return new WaitForFixedUpdate();
        frame  ;
    }
    // 继续执行后续逻辑
    Destroy(body.gameObject, 1f);
}

0 人点赞