简体   繁体   English

如何重新启动协程?

[英]How can I restart coroutine?

I am trying to implement a coroutine that moves an object to a specific point and then comes back to the origin (specified by me) as a coroutine in Unity, but the coroutine is not executed after returning to the origin.我正在尝试实现一个协程,它将 object 移动到特定点,然后作为 Unity 中的协程返回原点(由我指定),但协程在返回原点后未执行。 What's wrong?怎么了?

public class LineManager : MonoBehaviour
{
    public Vector3 positionToGo = new Vector3(0, -4, 0);
    IEnumerator coroutine;
    void Start()
    {
        coroutine = MoveToPosition(transform, positionToGo, 2f);
    }

    void Update()
    {
        if(transform.position.y == 4)
        {
            StartCoroutine(coroutine);
        }
    }

    public IEnumerator MoveToPosition(Transform transform, Vector3 position, float timeToMove)
    {
        var currentPos = transform.position;
        var t = 0f;
        while (t < 1 && currentPos.y > position.y)
        {
            t += Time.deltaTime / timeToMove;
            transform.position = Vector3.Lerp(currentPos, position, t);
            yield return null;
        }
            transform.position = new Vector3(0, 4, 0);
            StopCoroutine(coroutine);
    }
}

You don't really need to restart your routine for that.你真的不需要为此重新开始你的例行程序。

But first things first:但首先要做的是:

transform.position.y == 4

is risky as it is a direct float comparison and might fail.是有风险的,因为它是直接float比较并且可能会失败。 See Is floating point math broken?请参阅浮点数学是否损坏?

Anyways, back to the coroutine restarting.无论如何,回到协程重新启动。 Why not simply move without a routine at all为什么不干脆不按常规移动

public Vector3 positionToGo = new Vector3(0, -4, 0);
public float timeToMove = 2f;

private Vector3 originalPosition;
private float factor;

private void Awake()
{
    originalPosition = transform.position;
}

private void Update()
{
    if(factor >= 1)
    {
        factor = 0;
        transform.position = originalPosition;
    }
    else
    {
        factor += Time.deltaTime / timeToMove;
        transform.position = Vector3.Lerp(originalPosition, positionToGo, factor);
    }
}

As an alternative if you want to use the routine you can always simply make it loop作为替代方案,如果您想使用例程,您可以随时简单地使其循环

public Vector3 positionToGo = new Vector3(0, -4, 0);
public float timeToMove = 2f;

private IEnumerator Start()
{
    var originalPosition = transform.position;

    while(true)
    {
        for(var factor = 0f; factor < 1f; factor += Time.deltaTime / timeToMove)
        {
            transform.position = Vector3.Lerp(originalPosition, position, factor);
            yield return null;
        }

        transform.position = originalPosition;
    }
}

call the Coroutine in that IEnumerator with waitforseconds使用 waitforseconds 调用该 IEnumerator 中的协程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM