当协程依赖多个条件时,如何使用Unity StopCoroutine?

问题描述 投票:0回答:1

我最近一直在摆弄 Unity 中的协程功能,并意识到我似乎无法使用 StopCoroutine 命令来停止依赖于条件的协程。

我的代码如下:

horizontal = Input.GetAxisRaw("Horizontal");
        vertical = Input.GetAxisRaw("Vertical");

        Vector2 fwd = new Vector2(horizontal, vertical);
        fwd.Normalize();

        LayerMask layerMask = LayerMask.GetMask("Default"); //only looks for objects on the Default layer, means that players collider doesnt get hit by raycast

        RaycastHit2D hit = Physics2D.Raycast(raycastObject.transform.position, fwd, 50, layerMask); //raycast instantiates out in movement direction up to 50 units away
        Debug.DrawRay(raycastObject.transform.position, fwd * 50, Color.green); //editor raycast debug
        if (hit.collider != null && hit.collider.tag == "LightFood") //only interacts with 'Food' objects
        {
            IEnumerator liftCor = Lift(smallFruit * 2, hit.collider.gameObject);
            if (Input.GetKey(KeyCode.E))
            {
                if (antNum >= smallFruit) //this says that if there are less ants then required for the weight of the fruit (look above start function to see weights), then fruit isnt lifted
                {
                    StartCoroutine(liftCor); //lifts fruit according to its weight * 2 (since the weight is then divided by antnum, so its important cause math)
                    
                }
            }
            else
            {
                StopCoroutine(liftCor); //this seems not to be working :(
            }

        }
            
        

    private IEnumerator Lift(float weight, GameObject item)
    {
        weight = weight / antNum;
        Debug.Log(weight);
        yield return new WaitForSeconds(weight);
        item.SetActive(false);
    }

其中antNum和smallFruit是任意浮点数。

我已经尝试过使用字符串调用协程的 Unity 文档建议,或者(如代码所示)首先将协程归因于 IEnumerator 并从同一个变量调用它们,但我没有运气,我认为这可能是由于协程依赖于浮点和游戏对象。

如果您对如何解决此问题有任何建议,我将非常感激听到它们。 谢谢!

unity-game-engine coroutine ienumerator
1个回答
0
投票

每次调用

Lift
方法时,都会创建一个新的枚举器。所以你停止的是新的,但实际上你想停止的是前一个。

您的代码中还有另一个问题。当您按下

E
时,您将在每一帧启动一个新的协程,我认为这不是预期的。

解决方案是这样的,首先你应该定义一个协程对象来引用创建的协程。

private Coroutine coroutineLift;

然后你可以用它来关联新的协程并停止它。

if (Input.GetKey(KeyCode.E))
{
    if (antNum >= smallFruit && coroutineLift == null)
    {
        coroutineLift = StartCoroutine(Lift(smallFruit * 2, hit.collider.gameObject));                 
    }
}
else if (coroutineLift != null)
{
    StopCoroutine(coroutineLift);
}

如果你想在这个协程结束后继续创建新的协程,那么你还需要在

coroutineLift
结束时清除
Lift

private IEnumerator Lift(float weight, GameObject item)
{
    .....
    coroutineLift = null;
}
© www.soinside.com 2019 - 2024. All rights reserved.