Garzec Geschrieben 21. Januar 2018 Melden Share Geschrieben 21. Januar 2018 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 More sharing options...
Kojote Geschrieben 21. Januar 2018 Melden Share Geschrieben 21. Januar 2018 Du nutzt einmal Vector2 und einmal Vector3, dass funktioniert nicht. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Garzec Geschrieben 21. Januar 2018 Autor Melden Share Geschrieben 21. Januar 2018 @Kojote achso, den Parameter brauche ich für was anderes, aber fürs Beispiel hier ändere ich es ab Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Kojote Geschrieben 21. Januar 2018 Melden Share Geschrieben 21. Januar 2018 Eigentlich sollte er die Schleife übergehen. :-) Das false im Enumerator setzt er aber nur wenn er aus der Schleife wieder heraus kommt. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 21. Januar 2018 Melden Share Geschrieben 21. Januar 2018 "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 More sharing options...
Garzec Geschrieben 21. Januar 2018 Autor Melden Share Geschrieben 21. Januar 2018 @Kojote ich habe noch nicht so ganz verstanden, was du meinst. Also der Code ist falsch bzw. könnte Fehler aufkommen lassen? Danke dir @Zer0Cool Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 21. Januar 2018 Melden Share Geschrieben 21. Januar 2018 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 More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.