如何让脚本以一种简单的方式在 unity 中等待/睡眠 [英] How to make the script wait/sleep in a simple way in unity

查看:79
本文介绍了如何让脚本以一种简单的方式在 unity 中等待/睡眠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 TextUI.text = .... 之间加入睡眠功能,在每个短语之间等待 3 秒?

How can I put a sleep function between the TextUI.text = ...., to wait 3 seconds between each phrase?

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);

在 bash 中,它将是:

In bash, it would be:

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

但我不知道如何使用 C# 在 Unity 中执行此操作

but I can't figure out how to do this in Unity with C#

推荐答案

在 Unity 中等待的方法有很多种.它们真的很简单,但我认为值得介绍大多数方法:

There are many ways to wait in Unity. They are really simple but I think it's worth covering most ways to do it:

1.使用协程和 WaitForSeconds.

1.With a coroutine and WaitForSeconds.

这是迄今为止最简单的方法.把所有你需要等待一段时间的代码放在一个协程函数中,然后你可以用 等待秒.请注意,在协程函数中,您使用 StartCoroutine(yourFunction) 调用该函数.

The 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).

下面的例子将旋转 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.使用协程和 WaitForSecondsRealtime.

2.With a coroutine and WaitForSecondsRealtime.

WaitForSecondsWaitForSecondsRealtime 的唯一区别在于 WaitForSecondsRealtime 使用的是未缩放的等待时间,这意味着当使用 Time.timeScaleWaitForSecondsRealtime 函数不会受到影响,但 WaitForSeconds 会.

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.

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);
}


等待,仍然可以看到您等了多久:

3. 使用协程并使用 Time.deltaTime.

3.With a coroutine and incrementing a variable every frame with 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.

当你想用 boolean 变量中断等待/睡眠时,它也很好.这是可以使用 yield break; 的地方.

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.

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);
}

您仍然可以通过将 while 循环移动到另一个协程函数中并产生它来简化它,并且仍然能够看到它计数甚至中断计数器.

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.

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;
    }
}


等待/休眠直到变量改变或等于另一个值:

4.使用协程和 WaitUntil 功能:

4.With a coroutine and the WaitUntil function:

等到条件变为.一个例子是一个函数,它等待玩家的分数达到 100 然后加载下一个级别.

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.

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.使用协程和 WaitWhile 函数.

5.With a coroutine and the WaitWhile function.

等待条件为 true.一个例子是当你想在按下退出键时退出应用程序.

Wait while a condition is true. An example is when you want to exit app when the escape key is pressed.

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.使用调用 功能:


6.With the Invoke function:

您可以调用告诉 Unity 将来调用函数.当您调用 Invoke 函数时,您可以将在调用该函数之前等待的时间传递给它的第二个参数.下面的示例将在 5 秒后调用 feedDog() 函数,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.

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

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

7.使用 Update() 函数和 Time.deltaTime.

7.With the Update() function and Time.deltaTime.

它就像#3,只是它不使用协程.它使用 Update 函数.

It's just like #3 except that it does not use coroutine. It uses the Update function.

这样做的问题是它需要很多变量,所以它不会每次都运行,而是在等待后计时器结束时只运行一次.

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");
}


还有其他方法可以在 Unity 中等待,但您绝对应该知道上面提到的方法,因为这可以更轻松地在 Unity 中制作游戏.何时使用每种取决于具体情况.


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.

对于您的特定问题,这是解决方案:

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);
}

并且要从 start 或 Update 函数调用/启动协程函数,您可以使用

And to call/start the coroutine function from your start or Update function, you call it with

StartCoroutine (showTextFuntion());

这篇关于如何让脚本以一种简单的方式在 unity 中等待/睡眠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆