Jump to content
Unity Insider Forum

Enumeratoren verstehen


Garzec

Recommended Posts

Hallo,

ich tue mich echt schwer mit dem Verstehen von Enumeratoren. Ich habe vier Buttons, die den Spieler in eine bestimmte Richtung bewegen. Solange der Spieler sein Ziel noch nicht erreicht hat, soll der Input blockiert werden. 

    public void Move()
    {
        if (!isMoving) // nur bewegen, wenn der Spieler sich momentan nicht bewegt
        {
            StartCoroutine(MovePlayer());
        }
    }

    IEnumerator MovePlayer()
    {
        isMoving = true;

        Vector3 targetPosition = /* irgendeine Position */;

        while (transform.position != targetPosition)
        {
            transform.position = Vector3.MoveTowards(transform.position, targetPosition, info.MovementSpeed * Time.deltaTime);
            yield return null;
        }

        isMoving = false;
    }

Der Enumerator MUSS etwas zurückliefern, innerhalb der Schleife liefert er etwas zurück. Aber was ist, wenn die Schleife gar nicht läuft? Normalerweise meckert der Compiler doch, wenn nicht alle Pfade abgedeckt sind. Beispiel fürs Meckern:

int GetNumber()
{
    if(1 > 2)
    {
       return 5;
    }
}

Der Code oben ist aber ansonsten in Ordnung oder gibt es da Verbesserungsbedarf?

Link zu diesem Kommentar
Auf anderen Seiten teilen

"IEnumerator" ist eigentlich kein Rückgabewert in dem Sinne, sondern ein Interface. Über dieses Interface kann Unity die Coroutinen durchiterieren (ähnlich wie in einer foreach-Schleife).
Das yield-Statement steht dabei quasi für ein "MoveNext()" und springt damit zur nächsten Coroutine oder gibt an den "Mainloop" von Unity ab. Zugleich kann über das yield-Statement festgelegt werden, wann der nächste "Durchlauf" der Coroutine erfolgen soll (return null, WaitForSeconds, WaitForFixedUpdate, WaitForEndofFrame).
Wird nichts zurückgegeben (kein yield wird aufgerufen) endet die Coroutine.

Gerade entdeckt, es gibt sogar so interessante Dinge wie:
https://docs.unity3d.com/ScriptReference/WaitUntil.html

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nur ein kleine Verbesserung, die Position wohin der Spieler laufen soll gleich der Coroutine mitgeben:

    public void Move()
    {
        if (!isMoving) // nur bewegen, wenn der Spieler sich momentan nicht bewegt
        {
           IEnumerator coroutine = MovePlayer(transform.position + transform.forward * 5); // 5 Einheiten nach vorn
           StartCoroutine(coroutine);
        }
    }

    IEnumerator MovePlayer(Vector3 moveTo)
    {
        isMoving = true;

        Vector3 targetPosition = moveTo;

        while (transform.position != targetPosition)
        {
            transform.position = Vector3.MoveTowards(transform.position, targetPosition, info.MovementSpeed * Time.deltaTime);
            yield return null; // Durch "return null" befinden wir uns im "Updatezyklus", für Player mit RB besser "yield return new WaitForFixedUpdate()" verwenden
        }

        isMoving = false;
    }

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...