Hoe kan ik een slaapfunctie tussen de TextUI.text = ....
plaatsen om 3 seconden te wachten tussen elke zin?
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);
Ik heb al verschillende dingen geprobeerd, maar geen enkele heeft gewerkt, zoals deze:
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 zou het zijn:
echo "Welcome to Number Wizard!"
sleep 3
echo "The highest number you can pick is 1000"
sleep 3
.....
maar ik weet niet hoe ik dit moet doen in Unity met C#
Antwoord 1, autoriteit 100%
Er zijn veel manieren om te wachten in Unity. Het is heel eenvoudig, maar ik denk dat het de moeite waard is om de meeste manieren te bespreken om dit te doen:
1.Met een coroutine en WaitForSeconds
.
Dit is verreweg de eenvoudigste manier. Zet alle code die je even moet wachten in een coroutine-functie, dan kun je wachten met WaitForSeconds
. Merk op dat je in de coroutine-functie de functie aanroept met StartCoroutine(yourFunction)
.
Het onderstaande voorbeeld draait 90 graden, wacht 4 seconden, draait 40 graden en wacht 2 seconden, en roteert tenslotte 20 graden.
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.Met een coroutine en WaitForSecondsRealtime
.
Het enige verschil tussen WaitForSeconds
en WaitForSecondsRealtime
is dat WaitForSecondsRealtime
ongeschaalde wachttijd gebruikt, wat betekent dat bij het pauzeren van een spel met Time.timeScale
, de functie WaitForSecondsRealtime
zou niet worden beïnvloed, maar WaitForSeconds
wel.
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);
}
Wacht en kun nog steeds zien hoe lang je hebt gewacht:
3.Met een coroutine en het verhogen van een variabele elk frame met Time.deltaTime
.
Een goed voorbeeld hiervan is wanneer je de timer nodig hebt om op het scherm te laten zien hoe lang hij heeft gewacht. Eigenlijk als een timer.
Het is ook goed als je de wait/sleep wilt onderbreken met een boolean
-variabele als deze waar is. Dit is waar yield break;
kan worden gebruikt.
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);
}
Je kunt dit nog steeds vereenvoudigen door de while
-lus naar een andere coroutine-functie te verplaatsen en deze op te geven en ook nog steeds te kunnen zien tellen en zelfs de teller kunnen onderbreken.
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;
}
}
Wacht/slaap totdat de variabele verandert of gelijk is aan een andere waarde:
4.Met een coroutine en de WaitUntil
functie:
Wacht tot een voorwaarde true
wordt. Een voorbeeld is een functie die wacht tot de score van de speler 100
is en vervolgens het volgende niveau laadt.
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.Met een coroutine en de WaitWhile
functie.
Wacht terwijl een voorwaarde true
is. Een voorbeeld is wanneer u de app wilt verlaten wanneer de escape-toets wordt ingedrukt.
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.Met de Invoke
functie:
Je kunt tell Unity aanroepen om de functie in de toekomst aan te roepen. Wanneer u de functie Invoke
aanroept, kunt u de wachttijd doorgeven voordat u die functie aanroept naar zijn tweede parameter. In het onderstaande voorbeeld wordt de functie feedDog()
aangeroepen nadat 5
seconden de Invoke
wordt aangeroepen.
void Start()
{
Invoke("feedDog", 5);
Debug.Log("Will feed dog after 5 seconds");
}
void feedDog()
{
Debug.Log("Now feeding Dog");
}
7.Met de functie Update()
en Time.deltaTime
.
Het is net als #3behalve dat het geen coroutine gebruikt. Het gebruikt de functie Update
.
Het probleem hiermee is dat er zoveel variabelen voor nodig zijn dat het niet elke keer wordt uitgevoerd, maar slechts één keer wanneer de timer voorbij is na het wachten.
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");
}
Er zijn nog andere manieren om in Unity te wachten, maar je moet zeker de hierboven genoemde manieren kennen, want dat maakt het gemakkelijker om games in Unity te maken. Wanneer je ze allemaal moet gebruiken, hangt af van de omstandigheden.
Voor uw specifieke probleem is dit de oplossing:
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);
}
En om de coroutine-functie aan te roepen/starten vanuit je start- of update-functie, roep je deze aan met
StartCoroutine (showTextFuntion());
Antwoord 2, autoriteit 8%
U hebt correct WaitForSeconds gebruikt. Maar ik vermoed dat je geprobeerd hebt het zonder coroutines te gebruiken. Zo zou het moeten werken:
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);
}
Antwoord 3, autoriteit 5%
Met .Net 4.x kunt u Task-based Asynchronous Pattern (TAP) gebruiken om dit te bereiken:
// .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.");
}
}
dit is een functie om .Net 4.x met Unity te gebruiken, zie deze link voor een beschrijving ervan
en deze link voor een voorbeeldproject en vergelijk het met coroutine
Maar pas op, aangezien de documentatie zegt dat Dit is geen volledige vervanging met coroutine
Antwoord 4
hier is een eenvoudigere manier zonder StartCoroutine:
float t = 0f;
float waittime = 1f;
en binnen Update/FixedUpdate:
if (t < 0){
t += Time.deltaTIme / waittime;
yield return t;
}
Antwoord 5
Gebruik asynchrone en wacht
public void Start() {
doTask();
}
async void doTask() {
Debug.Log("Long running task started");
// wait for 5 seconds, update your UI
await Task.Delay(TimeSpan.FromSeconds(5f));
// update your UI
Debug.Log("Long running task has completed");
}
Antwoord 6
//Hier is een voorbeeld van een deel van mijn code om te wachten in Unity die ik heb gemaakt met behulp van een waarde en update die elke update dateert, zodra het de waarde is, zal het if-statement de taak uitvoeren.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnterCarCollider : MonoBehaviour
{
public GameObject player;
//Calls & Delcares vehicle objects
public GameObject Camera;
public VehicleControl ascript;
public Collider enterDriverCollider;
public Collider parkBreakCollider;
public GameObject enterVehicleDriverToolTip;
public int forStayInTime = 32;
public int timeInActiveTriggeredCollider;
private void Start()
{
ascript = GetComponent<VehicleControl>();
timeInActiveTriggeredCollider = 0;
}
private void OnTriggerStay(Collider other)
{
if (forStayInTime <= timeInActiveTriggeredCollider)
{
if (Input.GetKey(KeyCode.E))
{
ascript.enabled = !ascript.enabled;
Camera.active = true;
player.active = false;
enterDriverCollider.enabled = false;
parkBreakCollider.enabled = false;
}
// TODO: Enter car message
enterVehicleDriverToolTip.active = true;
}
timeInActiveTriggeredCollider++;
}
private void OnTriggerExit(Collider other)
{
enterVehicleDriverToolTip.active = false;
timeInActiveTriggeredCollider = 0;
}
private void Update()
{
if (enterDriverCollider.enabled is false)
{
timeInActiveTriggeredCollider = 0;
}
}
}