如何使脚本以统一的简单方式等待/睡眠
如何在TextUI.text = ....
之间TextUI.text = ....
一个sleep函数,在每个短语之间等待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);
我已经尝试了各种各样的东西,但没有奏效,这样:
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中将是:
echo "Welcome to Number Wizard!" sleep 3 echo "The highest number you can pick is 1000" sleep 3 .....
但我无法弄清楚我是如何在Unity中用C#做的
有很多方法可以在Unity中等待。 这很简单,但我认为值得涵盖大多数方法来做到这些:
1.使用协程和WaitForSeconds
。
这是迄今为止最简单的方法。 在coroutine函数中放置所需的所有代码等待一段时间,然后等待WaitForSeconds
。 请注意,在coroutine函数中,可以使用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
。
WaitForSeconds
和WaitForSecondsRealtime
之间的唯一区别是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); }
等等,仍然可以看到你等了多久:
3,使用协程并使用Time.deltaTime
每帧递增一个变量。
一个很好的例子就是当你需要计时器在屏幕上显示它等待了多长时间。 基本上就像一个计时器。
当你想用一个boolean
变量中断等待/睡眠时它也是好的。 这是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); }
您仍然可以通过将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; } }
等待/睡眠直到变量变化或等于另一个值 :
4.使用协同程序和WaitUntil
函数:
等到条件变为true
。 一个例子是等待玩家得分为100
然后加载下一级别的function。
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 Leve"); //Increment and Load next scene nextScene++; SceneManager.LoadScene(nextScene); }
5,具有协同程序和WaitWhile
function。
等待条件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.使用Invoke
function:
你可以打电话告诉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.使用Update()
函数和Time.deltaTime
。
就像#3一样,它不使用协程。 它使用Update
function。
这样做的问题是它需要这么多变量,以便它不会每次都运行,而只是在等待后计时器结束时运行一次。
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中制作游戏。 何时使用每一个取决于具体情况。
对于您的特定问题,这是解决方案:
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); }
要从您的启动或更新function调用/启动协同程序function,您可以使用它来调用它
StartCoroutine (showTextFuntion());
你使用WaitForSeconds是正确的。 但我怀疑你尝试使用它没有协同程序。 它应该如何工作:
public void SomeMethod() { StartCoroutine(SomeCoroutine()); } private IEnumerator SomeCoroutine() { TextUI.text = "Welcome to Number Wizard!"; yield return WaitForSeconds (3); TextUI.text = ("The highest number you can pick is " + max); yield return WaitForSeconds (3); TextUI.text = ("The lowest number you can pick is " + min); }