在Unity3d中以长循环显示进度

时间:2015-03-21 01:50:44

标签: loops unity3d progress-bar coroutine

我正在建造一个由数千个星系统组成的太空游戏。现在,有一个功能可以生成数千个系统。生成大约需要5-10秒,我希望有一个简单的进度条来更新进度中的用户。

经过一番搜索,我决定使用一个协程,但是有一点问题:当我调用函数生成星系统时,调用函数的代码继续运行,报告零星(因为它们没有'已经生成了。)

我有一种感觉,coroutines不适合我。基本上,我只是在寻找一种模拟Application.DoEvents来更新GUI的方法。

以下是我的代码示例:

// Start generating thousands of systems
StartCoroutine(GalacticMap.GenerateRandomGalaxy());
// after the universe is generated...
Game.myGalaxy.StarSystems = GalacticMap.myGalaxy.StarSystems;
// report back the number of systems
print(String.Format("Generated {0} systems", Game.myGalaxy.StarSystems.Count));

然而,GalacticMap.GenerateRandomGalaxy()我正在回归yield return new WaitForSeconds(0.1f);,效果不是我想要的:当生成仍然在时,执行会直到print语句去。

那我该怎么做?

编辑1:

我已经编写了一个示例代码来说明我的问题。

来电者代码:

Debug.Log ("Start generating");
StartCoroutine(GenerateMeGalaxy());
Debug.Log ("Finish generating");

我打电话给的代码:

public static IEnumerator  GenerateMeGalaxy ()
{
    Debug.Log ("GenerateMeGalaxy start");
    int numberOfStars = 1000;

    for (int i=0;i<=numberOfStars;i++)
    {
        // generate galaxy

        // display progress bar on screen
        Debug.Monitor(String.Format("{0}% completed", ((i*100)/numberOfStars)),2);
        yield return new WaitForSeconds(0.001f);
    }
    Debug.Log ("GenerateMeGalaxy end");
}

在上面的代码中,Debug.Log在屏幕上显示一个新行上的字符串,以便您可以读取以前记录的任何字符串。这是为了调试代码执行。 Debug.Monitor在屏幕上有一个固定的位置,将覆盖以前的字符串。这是我显示进度百分比的地方。运行此代码后我看到的是:

Start generating
GenerateMeGalaxy start
Finish generating
GenerateMeGalaxy end

我想看到的是:

Start generating
GenerateMeGalaxy start
GenerateMeGalaxy end
Finish generating

...而且进度更新发生在两者之间:

GenerateMeGalaxy start
Finish generating

1 个答案:

答案 0 :(得分:0)

我认为你误解了Unity协同程序的工作方式。 yield return new WaitForSeconds(0.1f)基本上说的是&#34;去做其他事情并在0.1秒之后再回到我身边#34;所以Unity自然会继续做其他事情,包括print语句。

您想要的是以下模式:

IEnumerator GenerateRandomGalaxy()
{
    int numSystems = 5000; // however many systems you want to generate
    foreach(int i = 0; i < numSystems; i++) 
    {
        // insert code here that generates system i

        // insert code here that updates the progress bar

        yield return null;
    }
    // put logic that prints out final number of systems generated here
}

这样做是生成一个系统,更新状态栏,然后 - 使用yield return null语句 - 告诉Unity接管(以便它做其他事情,包括渲染更新的进度条)然后回来继续循环。

最后,print语句仅在循环结束后才会发生,如您所愿。