【问题标题】:How to quit from nested Coroutines in Unity?如何退出 Unity 中的嵌套协程?
【发布时间】:2022-08-14 03:11:45
【问题描述】:

我正在创建自上而下的益智游戏,我使用基于网格的移动。我创建了一个移动角色的代码,如果角色正在推动盒子,它也会推动盒子。但我想让盒子看看它后面是否有任何东西,如果有东西,停止所有运动(本身和角色的)。所以我创建了两个类似的协程函数:

一、对于球员运动

private IEnumerator PlayerMove(Vector2 direction)
    {

        // check for wall collisions
        if (Physics2D.Raycast(playerTransform.position, direction, raycastDistance, wallLayer).collider is not null)
        {
            Animate(Animations.CantMove);
            yield break;
        }

        // check for box collisions
        else if (Physics2D.Raycast(playerTransform.position, direction, raycastDistance, box.boxLayer).collider is not null)
        {
            if ()
        }

        // changing fields
        isMoving = true;
        isPlayersTurn = false;


        // actual moving
        float elapsedTime = 0f;

        origPos = playerTransform.position;
        targetPos = origPos + direction;

        while (elapsedTime < timeToMove)
        {
            playerTransform.position = Vector2.Lerp(origPos, targetPos, (elapsedTime / timeToMove));
            elapsedTime += Time.deltaTime;
            yield return null;
        }

        playerTransform.position = targetPos;


        // changing fields
        isMoving = false;
        isBotTurn = true;
    }

第二,类似的,对于盒子移动:

public IEnumerator Move(Vector2 direction, float raycastDistance, LayerMask wallLayer, float timeToMove)
    {             
        // check for wall collisions
        if (Physics2D.Raycast(transform.position, direction, raycastDistance, wallLayer).collider is not null)
        {
            //do something
        }



        // actual moving
        float elapsedTime = 0f;

        Vector2 origPos, targetPos;

        origPos = transform.position;
        targetPos = origPos + direction;

        while (elapsedTime < timeToMove)
        {
            transform.position = Vector2.Lerp(origPos, targetPos, (elapsedTime / timeToMove));
            elapsedTime += Time.deltaTime;
            yield return null;
        }

        transform.position = targetPos;
    }

在第二种方法开始时,我使用 Physics2D.Raycast() 方法检查盒子后面是否没有墙。如果它注意到了什么,我想退出 PlayerMove() 和 BoxMove(),但如果没有,我希望两者都继续。我尝试使用异常,但协程似乎不喜欢它们。有什么办法可以解决这个问题吗?

  • 考虑使用简单的基于时间的插值函数而不是协程,因为如果使用不正确,协程类似于Application.DoEvents。此外,它从 c# 开发人员的角度教导坏习惯,并且很可能会导致常规 c# 工作中的私刑。

标签: c# unity3d game-development


【解决方案1】:

要停止当前协程的执行,您可以使用yield break;

要停止另一个协程的执行,您可以使用StopCoroutine

private Coroutine playerMoveCoroutine;

public void StartMoving(Vector2 direction)
{
    playerMoveCoroutine = StartCoroutine(PlayerMove(direction));
}

public void StopMoving()
{
    if(moveCoroutine != null)
    {
        StopCoroutine(moveCoroutine);
        moveCoroutine = null;
    }
}

所以停止这两个协程可以这样完成:

if (Physics2D.Raycast(transform.position, direction, raycastDistance, wallLayer).collider is not null)
{
    player.StopMoving();
    yield break;
}

【讨论】:

    猜你喜欢
    • 2013-09-11
    • 2020-01-14
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 2015-12-08
    相关资源
    最近更新 更多