c# - Cómo hacer que el guión espere/duerma de una manera simple en la unidad
unity3d monodevelop (3)
¿Cómo se puede poner entre
TextUI.text = ....
una función de reposo, para esperar 3 segundos entre cada frase?
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);
Ya probé varias cosas pero no funcionó, como esto:
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);
En bash sería:
echo "Welcome to Number Wizard!"
sleep 3
echo "The highest number you can pick is 1000"
sleep 3
.....
pero no puedo entender cómo hago esto en Unity con C #
Con .Net 4.x puede usar el patrón asincrónico basado en tareas (TAP) para lograr esto:
// .NET 4.x async-await
using UnityEngine;
using System.Threading.Tasks;
public class AsyncAwaitExample : MonoBehaviour
{
private async void Start()
{
Debug.Log("Wait.");
await WaitOneSecondAsync();
DoMoreStuff(); // Will not execute until WaitOneSecond has completed
}
private async Task WaitOneSecondAsync()
{
await Task.Delay(TimeSpan.FromSeconds(1));
Debug.Log("Finished waiting.");
}
}
esta es una característica para usar .Net 4.x con Unity, consulte este enlace para obtener una descripción al respecto
y este enlace para un proyecto de muestra y compararlo con la rutina
Pero teniendo en cuenta que la documentación dice que esto no es un reemplazo completo con la rutina
Estaba en lo correcto al usar WaitForSeconds. Pero sospecho que intentaste usarlo sin rutinas. Así es como debería funcionar:
public void SomeMethod()
{
StartCoroutine(SomeCoroutine());
}
private IEnumerator SomeCoroutine()
{
TextUI.text = "Welcome to Number Wizard!";
yield return new WaitForSeconds (3);
TextUI.text = ("The highest number you can pick is " + max);
yield return new WaitForSeconds (3);
TextUI.text = ("The lowest number you can pick is " + min);
}
Hay muchas formas de esperar en Unity. Es realmente simple, pero creo que vale la pena cubrir la mayoría de las formas de hacer esto:
1.
Con una corutina y
WaitForSeconds
.
El es, con mucho, la forma más simple.
Ponga todo el código que necesita esperar durante un tiempo en una función de rutina y luego puede esperar con
WaitForSeconds
.
Tenga en cuenta que en la función de rutina, llama a la función con
StartCoroutine(yourFunction)
.
El siguiente ejemplo rotará 90 grados, esperará 4 segundos, rotará 40 grados y esperará 2 segundos, y finalmente rotará rotará 20 grados.
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
.Con una rutina y
WaitForSecondsRealtime
.
La única diferencia entre
WaitForSeconds
y
WaitForSecondsRealtime
es que
WaitForSecondsRealtime
está usando tiempo sin escala para esperar, lo que significa que al pausar un juego con
Time.timeScale
, la función
WaitForSecondsRealtime
no se vería afectada, pero
WaitForSeconds
sí.
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);
}
Espera y aún podrás ver cuánto tiempo has esperado:
3.
Con una rutina e incrementando una variable cada cuadro con
Time.deltaTime
.
Un buen ejemplo de esto es cuando necesita que el temporizador muestre en la pantalla cuánto tiempo ha esperado. Básicamente como un temporizador.
También es bueno cuando desea interrumpir la espera / reposo con una variable
boolean
cuando es cierto.
Aquí es donde se
yield break;
puede ser usado.
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);
}
Todavía puede simplificar esto moviendo el ciclo while a otra función de rutina y cediéndola, y también podrá verlo contar e incluso interrumpir el contador.
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;
}
}
Esperar / dormir hasta que la variable cambie o sea igual a otro valor :
4.
Con una rutina y la función
WaitUntil
:
Espere hasta que se
true
una condición.
Un ejemplo es una función que espera que el puntaje del jugador sea
100
luego carga el siguiente nivel.
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.
Con una rutina y la función
WaitWhile
.
Espere mientras una condición es
true
.
Un ejemplo es cuando desea salir de la aplicación cuando se presiona la tecla de escape.
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.
Con la función
Invoke
:
Puede llamar a tell Unity para que llame a la función en el futuro.
Cuando llama a la función
Invoke
, puede pasar el tiempo de espera antes de llamar a esa función a su segundo parámetro.
El siguiente ejemplo llamará a la función
feedDog()
después de
5
segundos de que se
Invoke
.
void Start()
{
Invoke("feedDog", 5);
Debug.Log("Will feed dog after 5 seconds");
}
void feedDog()
{
Debug.Log("Now feeding Dog");
}
7.
Con la función
Update()
y
Time.deltaTime
.
Es igual que el n
. ° 3,
excepto que no usa corutina.
Utiliza la función
Update
.
El problema con esto es que requiere tantas variables que no se ejecutará todo el tiempo, sino solo una vez cuando el temporizador termine después de la espera.
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");
}
Todavía hay otras formas de esperar en Unity, pero definitivamente debes conocer las mencionadas anteriormente, ya que eso hace que sea más fácil hacer juegos en Unity. Cuándo usar cada uno depende de las circunstancias.
Para su problema particular, esta es la solución:
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);
}
Y para llamar / iniciar la función de rutina desde su función de inicio o Actualización, la llama con
StartCoroutine (showTextFuntion());