我最近一直在摆弄 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 并从同一个变量调用它们,但我没有运气,我认为这可能是由于协程依赖于浮点和游戏对象。
如果您对如何解决此问题有任何建议,我将非常感激听到它们。 谢谢!
每次调用
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;
}