如何在统一中以简单的方式使脚本等待/睡眠

Q:

How can I put a sleep function between the TextUI.text = ...., to wait 3 seconds between each phrase?
如何在TextUI.text = ....之间放置一个睡眠函数,以便在每个短语之间等待 3 秒?

public Text GuessUI;
public Text TextUI;

[...truncated...]

TextUI.text = "Welcome to Number Wizard!";
TextUI.text = ("The highest number you can pick is " + max);
TextUI.text = ("The lowest number you can pick is " + min);

I already tried various things but none have worked, such as this:
我已经尝试了各种方法,但没有一个有效,例如:

TextUI.text = "Welcome to Number Wizard!";
yield WaitForSeconds (3);
TextUI.text = ("The highest number you can pick is " + max);
yield WaitForSeconds (3);
TextUI.text = ("The lowest number you can pick is " + min);

In bash, it would be:
在 bash 中,它将是:

echo "Welcome to Number Wizard!"
sleep 3
echo "The highest number you can pick is 1000"
sleep 3
.....

but I can’t figure out how to do this in Unity with C#
但我不知道如何在 Unity 中使用 C# 执行此操作

A:

There are many ways to wait in Unity. They are really simple but I think it’s worth covering most ways to do it:
Unity中有多种等待方式。它们非常简单,但我认为值得涵盖大多数方法:

1.With a coroutine and WaitForSeconds.
1.带有协程和WaitForSeconds 。

This is by far the simplest way. Put all the code that you need to wait for some time in a coroutine function then you can wait with WaitForSeconds. Note that in coroutine function, you call the function with StartCoroutine(yourFunction).
这是迄今为止最简单的方法。将需要等待一段时间的所有代码放入协程函数中,然后就可以使用WaitForSeconds等待。请注意,在协程函数中,您可以使用StartCoroutine(yourFunction)调用该函数。

Example below will rotate 90 deg, wait for 4 seconds, rotate 40 deg and wait for 2 seconds, and then finally rotate rotate 20 deg.
下面的示例将旋转 90 度,等待 4 秒,旋转 40 度并等待 2 秒,最后旋转 20 度。

void Start()
{
    StartCoroutine(waiter());
}

IEnumerator waiter()
{
    //Rotate 90 deg
    transform.Rotate(new Vector3(90, 0, 0), Space.World);

    //Wait for 4 seconds
    yield return new WaitForSeconds(4);

    //Rotate 40 deg
    transform.Rotate(new Vector3(40, 0, 0), Space.World);

    //Wait for 2 seconds
    yield return new WaitForSeconds(2);

    //Rotate 20 deg
    transform.Rotate(new Vector3(20, 0, 0), Space.World);
}

2.With a coroutine and WaitForSecondsRealtime.
2.带有协程和WaitForSecondsRealtime 。

The only difference between WaitForSeconds and WaitForSecondsRealtime is that WaitForSecondsRealtime is using unscaled time to wait which means that when pausing a game with Time.timeScale, the WaitForSecondsRealtime function would not be affected but WaitForSeconds would.
WaitForSecondsWaitForSecondsRealtime之间的唯一区别是WaitForSecondsRealtime使用未缩放的时间来等待,这意味着当使用Time.timeScale暂停游戏时, WaitForSecondsRealtime函数不会受到影响,但WaitForSeconds会受到影响。

void Start()
{
    StartCoroutine(waiter());
}

IEnumerator waiter()
{
    //Rotate 90 deg
    transform.Rotate(new Vector3(90, 0, 0), Space.World);

    //Wait for 4 seconds
    yield return new WaitForSecondsRealtime(4);

    //Rotate 40 deg
    transform.Rotate(new Vector3(40, 0, 0), Space.World);

    //Wait for 2 seconds
    yield return new WaitForSecondsRealtime(2);

    //Rotate 20 deg
    transform.Rotate(new Vector3(20, 0, 0), Space.World);
}

Wait and still be able to see how long you have waited:
等待,仍然可以看到您等待了多长时间:

3.With a coroutine and incrementing a variable every frame with Time.deltaTime.
3.使用协程并使用Time.deltaTime每帧递增一个变量。

A good example of this is when you need the timer to display on the screen how much time it has waited. Basically like a timer.
一个很好的例子是当您需要计时器在屏幕上显示它已经等待了多长时间时。基本上就像一个计时器。

It’s also good when you want to interrupt the wait/sleep with a boolean variable when it is true. This is where yield break; can be used.
当您想在boolean变量为 true 时中断等待/睡眠时,这也很好。这就是yield break;可以使用。

bool quit = false;

void Start()
{
    StartCoroutine(waiter());
}

IEnumerator waiter()
{
    float counter = 0;
    //Rotate 90 deg
    transform.Rotate(new Vector3(90, 0, 0), Space.World);

    //Wait for 4 seconds
    float waitTime = 4;
    while (counter < waitTime)
    {
        //Increment Timer until counter >= waitTime
        counter += Time.deltaTime;
        Debug.Log("We have waited for: " + counter + " seconds");
        //Wait for a frame so that Unity doesn't freeze
        //Check if we want to quit this function
        if (quit)
        {
            //Quit function
            yield break;
        }
        yield return null;
    }

    //Rotate 40 deg
    transform.Rotate(new Vector3(40, 0, 0), Space.World);

    //Wait for 2 seconds
    waitTime = 2;
    //Reset counter
    counter = 0;
    while (counter < waitTime)
    {
        //Increment Timer until counter >= waitTime
        counter += Time.deltaTime;
        Debug.Log("We have waited for: " + counter + " seconds");
        //Check if we want to quit this function
        if (quit)
        {
            //Quit function
            yield break;
        }
        //Wait for a frame so that Unity doesn't freeze
        yield return null;
    }

    //Rotate 20 deg
    transform.Rotate(new Vector3(20, 0, 0), Space.World);
}

You can still simplify this by moving the while loop into another coroutine function and yielding it and also still be able to see it counting and even interrupt the counter.
您仍然可以通过将while循环移至另一个协程函数并生成它来简化此操作,并且仍然能够看到它计数甚至中断计数器。

bool quit = false;

void Start()
{
    StartCoroutine(waiter());
}

IEnumerator waiter()
{
    //Rotate 90 deg
    transform.Rotate(new Vector3(90, 0, 0), Space.World);

    //Wait for 4 seconds
    float waitTime = 4;
    yield return wait(waitTime);

    //Rotate 40 deg
    transform.Rotate(new Vector3(40, 0, 0), Space.World);

    //Wait for 2 seconds
    waitTime = 2;
    yield return wait(waitTime);

    //Rotate 20 deg
    transform.Rotate(new Vector3(20, 0, 0), Space.World);
}

IEnumerator wait(float waitTime)
{
    float counter = 0;

    while (counter < waitTime)
    {
        //Increment Timer until counter >= waitTime
        counter += Time.deltaTime;
        Debug.Log("We have waited for: " + counter + " seconds");
        if (quit)
        {
            //Quit function
            yield break;
        }
        //Wait for a frame so that Unity doesn't freeze
        yield return null;
    }
}

Wait/Sleep until variable changes or equals to another value:
等待/睡眠,直到变量更改或等于另一个值

4.With a coroutine and the WaitUntil function:
4.使用协程和WaitUntil函数:

Wait until a condition becomes true. An example is a function that waits for player’s score to be 100 then loads the next level.
等到条件true 。一个示例是等待玩家得分达到100然后加载下一个级别的函数。

float playerScore = 0;
int nextScene = 0;

void Start()
{
    StartCoroutine(sceneLoader());
}

IEnumerator sceneLoader()
{
    Debug.Log("Waiting for Player score to be >=100 ");
    yield return new WaitUntil(() => playerScore >= 10);
    Debug.Log("Player score is >=100. Loading next Level");

    //Increment and Load next scene
    nextScene++;
    SceneManager.LoadScene(nextScene);
}

5.With a coroutine and the WaitWhile function.
5.带有协程和WaitWhile函数。

Wait while a condition is true. An example is when you want to exit app when the escape key is pressed.
等待条件true 。一个例子是当您想在按下退出键时退出应用程序。

void Start()
{
    StartCoroutine(inputWaiter());
}

IEnumerator inputWaiter()
{
    Debug.Log("Waiting for the Exit button to be pressed");
    yield return new WaitWhile(() => !Input.GetKeyDown(KeyCode.Escape));
    Debug.Log("Exit button has been pressed. Leaving Application");

    //Exit program
    Quit();
}

void Quit()
{
    #if UNITY_EDITOR
    UnityEditor.EditorApplication.isPlaying = false;
    #else
    Application.Quit();
    #endif
}

6.With the Invoke function:
6 、 Invoke函数:

You can call tell Unity to call function in the future. When you call the Invoke function, you can pass in the time to wait before calling that function to its second parameter. The example below will call the feedDog() function after 5 seconds the Invoke is called.
您可以调用告诉Unity以后调用该函数。当您调用Invoke函数时,您可以将调用该函数之前等待的时间传递给其第二个参数。下面的示例将在调用Invoke 5秒后调用feedDog()函数。

void Start()
{
    Invoke("feedDog", 5);
    Debug.Log("Will feed dog after 5 seconds");
}

void feedDog()
{
    Debug.Log("Now feeding Dog");
}

7.With the Update() function and Time.deltaTime.
7.使用Update()函数和Time.deltaTime 。

It’s just like #3 except that it does not use coroutine. It uses the Update function.
它与#3类似,只是它不使用协程。它使用Update功能。

The problem with this is that it requires so many variables so that it won’t run every time but just once when the timer is over after the wait.
这样做的问题是它需要太多变量,因此它不会每次都运行,而是在等待后计时器结束时运行一次。

float timer = 0;
bool timerReached = false;

void Update()
{
    if (!timerReached)
        timer += Time.deltaTime;

    if (!timerReached && timer > 5)
    {
        Debug.Log("Done waiting");
        feedDog();

        //Set to false so that We don't run this again
        timerReached = true;
    }
}

void feedDog()
{
    Debug.Log("Now feeding Dog");
}

There are still other ways to wait in Unity but you should definitely know the ones mentioned above as that makes it easier to make games in Unity. When to use each one depends on the circumstances.
在 Unity 中还有其他等待的方法,但您绝对应该知道上面提到的方法,因为这样可以更轻松地在 Unity 中制作游戏。何时使用每一种取决于具体情况。

For your particular issue, this is the solution:
对于您的特定问题,这是解决方案:

IEnumerator showTextFuntion()
{
    TextUI.text = "Welcome to Number Wizard!";
    yield return new WaitForSeconds(3f);
    TextUI.text = ("The highest number you can pick is " + max);
    yield return new WaitForSeconds(3f);
    TextUI.text = ("The lowest number you can pick is " + min);
}

And to call/start the coroutine function from your start or Update function, you call it with
要从 start 或 Update 函数调用/启动协程函数,您可以使用

StartCoroutine (showTextFuntion());
912sy.com下载资源均来源于网络,仅供学习和参考使用,版权归原作者所有,勿作商业用途,请在下载后24小时之内自觉删除。
本站发布的内容若无意中侵犯到您的权益,请联系我们,本站将在一个工作日内删除。如遇到任何问题请联系客服QQ:2385367137
912sy » 如何在统一中以简单的方式使脚本等待/睡眠