【问题标题】:I do not know if I used too much 'yield return new WaitForSeconds' in the coroutine function不知道是不是在协程函数中使用了太多的 'yield return new WaitForSeconds'
【发布时间】:2018-12-18 22:47:17
【问题描述】:

** Unity5.6.5f1 / C#

我使用协程来运行动画。

而不是在更新函数中创建多个 if 语句,

我认为协程会更好。

但我认为我使用 'yield return new WaitForSeconds' 太多了,

这样写协程很常见吗?

private IEnumerator AnimationControl()
{
    yield return new WaitForSeconds(41f);        
    objAni.gameObject.SetActive(true);
    obj2Ani.gameObject.SetActive(true);
    obj3Ani.gameObject.SetActive(true);
    objAni.Play("Stay");
    obj2Ani.Play("Stay");
    obj3Ani.Play("Stay");

    yield return new WaitForSeconds(5.667f);        
    objAni.Play("Run");
    obj2Ani.Play("Run");
    obj3Ani.Play("Action");

    yield return new WaitForSeconds(3.666f);
    objAni.Play("Fire01");

    yield return new WaitForSeconds(2.334f);
    obj3Ani.Play("Panic");
    obj2Ani.gameObject.SetActive(false);

    yield return new WaitForSeconds(8.333f);
    objAni.Play("Fire02");

    yield return new WaitForSeconds(6.333f);      
    objAni.Play("Fire03");

    yield return new WaitForSeconds(6.1337f);       
    obj3Ani.Play("Stay");
    objAni.Play("Stay");

    yield return new WaitForSeconds(3.2003f);        
    obj3Ani.Play("Surprise02");
    objAni.Play("Surprise");

    yield return new WaitForSeconds(3.333f);                
    obj3Ani.Play("Run");
    objAni.Play("Run");

    yield return new WaitForSeconds(6f);
    objAni.Play("Stay");

    yield return new WaitForSeconds(1.667f);      
    objAni.Play("Run");

    yield return new WaitForSeconds(2.333f);        
    obj3Ani.gameObject.SetActive(false);

    yield return new WaitForSeconds(0.667f);        
    objAni.gameObject.SetActive(false);

    yield return new WaitForSeconds(1.333f);
    textObj.SetActive(false);

    yield return new WaitForSeconds(2.667f);
    endingObj.SetActive(true);
    allObj.SetActive(false);
}

感谢阅读。

【问题讨论】:

  • 这看起来就像一场等待发生的灾难。您应该研究如何在 Unity 中制作正确的动画。
  • 最好在每次等待后提及并显示您正在运行的代码。我认为这将决定是否有更好的方法来做到这一点
  • 看起来您正在尝试制作过场动画。协程可能会起作用,但正确的做法是使用 Animators 和 Timelines。
  • 我添加了代码。

标签: c# unity3d coroutine


【解决方案1】:

这正是协程的用途,即顺序执行许多代码,甚至随时等待。这不是太多。我看到的唯一问题是每次都创建新的WaitForSeconds。如果您知道等待的时间或者您对时间进行了硬编码,请在函数外部声明WaitForSeconds,然后针对它们屈服。这实际上取决于您调用AnimationControl 函数的频率。

例如,

private IEnumerator AnimationControl()
{
    yield return new WaitForSeconds(41f);
    objAni.gameObject.SetActive(true);
    obj2Ani.gameObject.SetActive(true);
    obj3Ani.gameObject.SetActive(true);
    objAni.Play("Stay");
    obj2Ani.Play("Stay");
    obj3Ani.Play("Stay");

    yield return new WaitForSeconds(5.667f);
    objAni.Play("Run");
    obj2Ani.Play("Run");
    obj3Ani.Play("Action");
}

变成

WaitForSeconds wTime1 = new WaitForSeconds(41f);
WaitForSeconds wTime2 = new WaitForSeconds(5.667f);

private IEnumerator AnimationControl()
{
    yield return wTime1;
    objAni.gameObject.SetActive(true);
    obj2Ani.gameObject.SetActive(true);
    obj3Ani.gameObject.SetActive(true);
    objAni.Play("Stay");
    obj2Ani.Play("Stay");
    obj3Ani.Play("Stay");

    yield return wTime2;
    objAni.Play("Run");
    obj2Ani.Play("Run");
    obj3Ani.Play("Action");
}


如果你真的想减少WaitForSeconds 代码,你可以围绕它创建一个包装类。这个类应该保持等待的时间甚至更好,WaitForSeconds 实例然后使用Action 来表示等待后要执行的代码。创建这个classList,循环它,等待然后执行Action 变量中的代码。

包装类:

public class AnimControlInfo
{
    public WaitForSeconds waitTime;
    public Action action;
}

创建一个列表:

List<AnimControlInfo> animInfo = new List<AnimControlInfo>();

初始化List,使其可以在AnimationControl函数中使用:

void InitControlAnimInfo()
{
    AnimControlInfo aI1 = new AnimControlInfo();
    aI1.waitTime = new WaitForSeconds(41f);
    aI1.action = delegate
    {
        objAni.gameObject.SetActive(true);
        obj2Ani.gameObject.SetActive(true);
        obj3Ani.gameObject.SetActive(true);
        objAni.Play("Stay");
        obj2Ani.Play("Stay");
        obj3Ani.Play("Stay");
    };

    AnimControlInfo aI2 = new AnimControlInfo();
    aI2.waitTime = new WaitForSeconds(5.667f);
    aI2.action = delegate
    {
        objAni.Play("Run");
        obj2Ani.Play("Run");
        obj3Ani.Play("Action");
    };

    //Add to List
    animInfo.Add(aI1);
    animInfo.Add(aI2);
}

然后你的新 AnimationControl 函数等待并播放动画或激活/取消激活 GameObects:

private IEnumerator AnimationControl()
{
    //Loop over the List, wait then do action
    for (int i = 0; i < animInfo.Count; i++)
    {
        yield return animInfo[i].waitTime;
        if (animInfo[i].action != null)
            animInfo[i].action();
    }
}

AnimationControl 函数中的代码量已减少。它还减少了对WaitForSeconds 类的过度使用。

【讨论】:

    猜你喜欢
    • 2016-06-15
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2018-11-09
    • 2023-03-26
    • 2021-11-27
    • 1970-01-01
    相关资源
    最近更新 更多