Hoe het script op een eenvoudige manier in eenheid te laten wachten/slapen

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 WaitForSecondsen WaitForSecondsRealtimeis dat WaitForSecondsRealtimeongeschaalde wachttijd gebruikt, wat betekent dat bij het pauzeren van een spel met Time.timeScale, de functie WaitForSecondsRealtimezou niet worden beïnvloed, maar WaitForSecondswel.

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 WaitUntilfunctie:

Wacht tot een voorwaarde truewordt. Een voorbeeld is een functie die wacht tot de score van de speler 100is 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 WaitWhilefunctie.

Wacht terwijl een voorwaarde trueis. 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 Invokefunctie:

Je kunt tell Unity aanroepen om de functie in de toekomst aan te roepen. Wanneer u de functie Invokeaanroept, kunt u de wachttijd doorgeven voordat u die functie aanroept naar zijn tweede parameter. In het onderstaande voorbeeld wordt de functie feedDog()aangeroepen nadat 5seconden de Invokewordt 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;
        }
    }
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes