是' IEnumerator'通过'产生WaitForSeconds'来调用每一帧。

时间:2017-07-14 10:50:21

标签: c# unity3d

以下是两个功能的示例。一个使用Update,另一个使用IEnumerator。我知道每帧都会调用Update函数。 我的问题: 每个帧都会调用IEnumerator吗?

注意:我使用的是yield WaitForSeconds,而不是yield WaitForEndOfFrameyield null

更新功能(示例1):

//_ratePerSecond is how often the functions must execute
void Update()
{
    if ((CurrentPoints >= MinPoints) && Time.time >= _timeToChangeValue)
    {
        _timeToChangeValue = Time.time + _ratePerSecond;
        CurrentPoints += 1
    }
}

IEnumerator函数(示例2):

//this is called with StartCoroutine(ChangeValue());
IEnumerator ChangeValue()
{
    while (true)
    {
        yield return new WaitForSeconds(_ratePerSecond);

        if (CurrentPoints >= MinPoints)
        {
            CurrentPoints += 1;
        }
    }
}

更新

以下是在示例1和1中运行功能的10000个对象完成的性能测试。 2.以红色突出显示的是Update功能(示例1),以绿色突出显示为IEnumerator功能(示例2)。

使用0-1秒的随机延迟: enter image description here

使用1-2秒的随机延迟: enter image description here

性能测试的结论Update函数的效率较低。当延迟更大时,IEnumerator表现得更好。

1 个答案:

答案 0 :(得分:1)

  

IEnumerator还调用了每一帧吗?

在您的问题中使用协同程序功能,答案是

WaitForSeconds函数将暂停 ChangeValue()函数,直到等待指定的(_ratePerSecond)秒为止,然后它将执行代码while循环,再次跳回while循环的开头并再次暂停(_ratePerSecond)秒。在StopCoroutine循环中调用StopAllCoroutines / yield breakwhile后,此操作将重复停止。

以下是Update函数中代码的协程版本。

IEnumerator ChangeValue()
{
    while (true)
    {    
        if ((CurrentPoints >= MinPoints) && Time.time >= _timeToChangeValue)
        {
            _timeToChangeValue = Time.time + _ratePerSecond;
            CurrentPoints += 1;
        }

        //Wait for a frame
        yield return null;
    }
}

请注意,您必须使用StartCoroutine(ChangeValue());而不是ChangeValue();

来调用此功能