4

我创建了一个简单的 lerp 动画,它使用以下代码将对象从一个地方移动到另一个地方:

public IEnumerator Move(Vector3 position, Transform transform, float animationTime = 1)
{
float timePassed = 0;
transform.position = Vector3.Lerp(startPos, position, timePassed /animationTime);
timePassed += Time.deltaTime;
yield return null;
}

我从另一个脚本中调用它。但我希望它在动画之后做点什么。 如果我在动画之前创建一个Coroutine并使用结束,它会导致错误。yield return WaitForSeconds(animationTime);Coroutine

我也尝试过创建变量来计算经过的时间(就像在动画中一样),但无济于事……</p>

我究竟做错了什么

编辑: 我无法更改 Move 函数,因为它在其他类中使用,我想让它尽可能通用

4

4 回答 4

1

与动画“同时”运行的协程?听起来它很容易在不同的fps上中断。

我强烈建议您在最后一个关键帧上使用AnimationEvent 。只需在动画中创建公共方法和关键帧事件,然后选择方法。最后会被调用。

于 2019-08-15T11:38:44.057 回答
0

您可以使用协程并在每一帧循环,循环完成后您可以触发回调。一个简单的例子可以是:

public IEnumerator Move(Vector3 position, Transform transform, float animationTime = 1, Action callback = null)
{
    float lerp = 0;
    do
    {
        lerp += Time.deltaTime / animationTime;
        transform.position = Vector3.Lerp(startPos, position, lerp);
        yield return null; // wait for the end of frame
    } while (lerp < 1);

    if (callback != null)
        callback();
}

PS:我没有在编辑器中测试这段代码。它可能有任何错字。

于 2019-08-15T11:49:29.070 回答
0

你可以把它放在协程中:

float timePassed=0.0f;
while(timePassed<=animationTime)
{
 transform.position = Vector3.Lerp(startPos, position, timePassed /animationTime);
 timePassed += Time.deltaTime;
 yield return null;
}
//all the stuff you want to do after the animation ended
于 2019-08-15T11:50:22.467 回答
0

您可以尝试在协程完成后使用它来发送返回值:

void Move(Vector3 position, Transform transform, float animationTime = 1) {

StartCoroutine(DoMove(position, transform, (moveIsDone) => {if(moveIsDone) { ... };});


IEnumerator DoMove(Vector3 position, Transform transform, float animationTime, System.Action<bool> callback)
{

    float timer = 0f;
    while(timer < 1f)
    {
        timer += Time.deltaTime / animationTime;
        transform.position = Vector3.Lerp(startPos, position, timer);
        yield return null;
    }
    callback(true);

}
于 2019-08-15T12:01:14.277 回答