Jump to content
Unity Insider Forum

Animator reagiert nicht


Kojote

Recommended Posts

Grüße!

Ich ärgere mich jetzt schon seit mehreren Stunden mit dem Animator rum und finde keinen Fehler. Ich habe einen Charakter, Controller war dazu und funktioniert auch. Nun wollte ich eine weitere Animation einbauen, die mit dazu war: "die01"

Ich habe mal die Bilder vom Animator angehangen. Ich habe Verbindungen geschaft von "Wald" und "Run". Wenn es zu einer Kollision kommt, soll per "isDeath" die Animation "die01" abgespielt werden. Jedoch, sobald die Kollision passiert, kehrt er in "idle" zurück. Seht ihr den Fehler?

Grüße von Kojote

Death 1.jpg

Death 2.jpg

Death 3.jpg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn du im State "CrippledWalk" bist gibt es 4 Möglichkeiten für einen Folgezustand. Wenn du "isDeath = true" setzt, gibt es immer noch 3 mögliche Übergange die du prüfen musst. Erst wenn die anderen 3 Übergänge blockiert sind, geht er mit Sicherheit in den Death-Zustand über. Du hast nur einen Übergang oben abgebildet, so daß man nicht sieht, welche Bedingungen die anderen 3 Übergange haben. Wenn beispielsweise die Bedingung für den Übergang "CrippledWalk->idle3" erfüllt ist, dann wird er den Übergang "CrippledWalk->death" niemals ausführen (Reihenfolge der Übergänge).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich gehe davon aus, dass die Transitions von walk und run zu idle die Geschwindigkeit mit abfragen. Und wahrscheinlich setzt du die Geschwindigkeit bei einer Kollision auf 0.
Ja und dann kommt es wahrscheinlich zum Sprung nach idle, bevor der tot eintritt. Von Idle zum Tot gibt es keine transition und deswegen auch keinen tot.
Bau in die Transitions von run und walk nach idle einfach noch isDeath mit ein. Also isDeath - false.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

OK, ich habs nun noch mal probiert, in dem ich von Idle direkt eine Verbindung zu Death machte. Es verhällt sich so, dass von Walk oder Run erst zurück zu Idle gegangen wird, dann die Idle Animation abgespielt wird und dann der Death kommt. Ich hab mal ein paar Bilder angehangen, verstehn tuh ichs nicht. Ich setze ja im Script extra alles auf False, um andere Animationen zu starten und nur Death auf True.

 

Animator 1.jpg

Animator 2.jpg

Animator 3.jpg

Animator 4.jpg

Animator 5.jpg

Animator 6.jpg

Animator 7.jpg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Bei dem Übergang zu "death" würde ich "has Exit Time" herausnehmen, ansonsten spielt er die aktuelle Animation noch ab und stirbt erst dann :) 
Aber wie gesagt wenn er sich bei der Collision im Zustand "crippledWalk" befindet und erst nach "Idle" geht und dann erst zu "death" stimmt da schon was nicht.

btw. du kannst den Zustandsautomaten im laufenden Spiel beobachten:
- animiertes Objekt auswählen
- Spiel ohne Maximieren starten
- Animator-Tab auswählen

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ah, das hilt auch schon mal weiter. Ich habe jetzt mal von dem Code hier:

private IEnumerator Kollision() {
        Debug.Log("Reagiert");
        //steuerungDeaktiviert = true;
        //animator.SetBool("isIdle", false);
        //animator.SetBool("crippled", false);
        //animator.SetBool("isRun", false);
        animator.SetBool("isDeath", true);
        yield return new WaitForFixedUpdate();
    }

Alles mal bis auf Death raus genommen, dazu noch jetzt dein Exit und sieht ganz gut aus! :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was hat du denn für den Zustand "CrippledWalk->idle" gesetzt? Ich vermute mal crippled = false?
Damit geht er nach Idle zurück sobald du animator.SetBool("crippled", false) setzt und dies ist die Ursache für den Sprung nach Idle.

Wäre interessant was er macht bei:

  animator.SetBool("isDeath", true);
  animator.SetBool("isIdle", false);      
  animator.SetBool("crippled", false);
  animator.SetBool("isRun", false);
        

Wenn er dann immer noch nach Idle geht, kannst du auch die Bedingungen an der Transition umsortieren, also hier (c > d nach oben):
Animator 1.jpg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Möglichkeit 1  - setzen des isDeath bools zuerst (funktioniert aber vermutlich nicht):

  animator.SetBool("isDeath", true);
  
  animator.SetBool("isIdle", false);      
  animator.SetBool("crippled", false);
  animator.SetBool("isRun", false);

Möglichkeit 2 - Umsortieren der Bedingungen (Transitions) am State:
"crippeldWalk -> death" als Bedingung nach oben!

Da ich denke er arbeitet die Bedingungen von oben nach unten ab ...

Animator 1.jpg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Zitat

Möglichkeit 2 - Umsortieren der Bedingungen (Transitions) am State:
"crippeldWalk -> death" als Bedingung nach oben!

Hatte ich schon probiert, funktioniert leider nicht.

Zitat

Möglichkeit 1  - setzen des isDeath bools zuerst (funktioniert aber vermutlich nicht):

Du wirst lachen, aber das funktioniert sogar. :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ok, interessant. 
Hintergrundinfo: Hier sieht man gut, was der Unterschied zwischen Trigger und Bool ist. Durch die Verwendung von Bool entsteht obiges Problem. Wenn man immer einen Trigger verwendet, dann kann der Zustand nicht "unkontrolliert" überspringen. Aber damit meine ich nicht, das Bool nicht auch seine Berechtigung hat, man muss eben nur genau aufpassen, wie man es verwendet.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Der Trigger stellt sicher, daß nur 1 Zustandswechsel erfolgt. Bei Bool kann es dir passieren (je nachdem wie man die Transitionen setzt), daß mehrere Übergange erfolgen.

Zustand A  -> (isB == true) -> Zustand B -> irgendwas -> Zustand C
Zustand A  <- irgendwas <- Zustand C

Code:
- isB = true
=> wechselt nach B
- irgendwas 
=> wechselt nach C
- irgendwas 
=> wechselt nach A
=> wechselt nach B (ggf. ungewollter Zustandsübergang)

*irgendwas
 Steht für eine beliebige Bedingung die einen Zustandswechsel erzeugt

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich weiß nicht. Ich guck mir das hier gerade an und irgendwie zeigen die Bilder, bis auf eines nichts, was interessant wäre.

Wenn man über eine oder mehrere Boolsche Variablen arbeitet, dann muss man eben auch schauen, dass man alle Bedingungen mit einbezieht.
Ich habe leider noch nicht ein Bild einer Transition von Run zu Idle oder von Walk zu Idle gesehen. Wird dort über ne Boolsche Varriable gesteuert oder ist da die Geschwindigkeit mit bei, die ich ja in den Parametern links sehen kann?!

Wie auch immer, wenn du bei der den Transitions in Richtung idle einfach noch eine weitere Bedingung hinzugefügt hättest, und zwar die isDeath  =  Flase. Dann würde wirklich nur nach Idle gegangen, wenn der Kerle nicht tot ist. Total egal, ob idle true oder walk false ist (ich weiß leider immer noch nicht welche Bedingung(en) du da genommen hast).

Von Grundsatz her ist es wichtig, dass alle möglichen Überblendungen auch mit transitions bestückt sind. Wenn man in Idle nicht sterben kann ( was eher unwahrscheinlich ist) dann muss man auch keine Verbindung zum death erstellen. Man muss aber dann nicht nur definieren, wann es nach idle gehen darf oder soll, sondern auch wann es nicht nach idle gehen darf!
Deswegen auch ruhig mal 2 Bedingungen in eine Transition setzen.

Man kann natürlich auch mit Triggern arbeiten, die sind aber nicht unbedingt die bessere Wahl, denn sie machen auch Probleme. Es kann nämlich schnell mal vorkommen, dass 2 Trigger im selben frame gesendet werden und dann gibt Abarbeitungsprobleme.
Wird ein Trigger gesendet, aber er hat keine Bewandnis in dem momentanen State, dann bleibt das Triggersignal stehen oder erreicht keinen der was damit anfangen kann. Beides schon erlebt.
Trigger gehen immer dann gut, wenn man sie vom anyState aus sendet. Alle anderen Verwendungen von Triggern sind in meinen Augen problematisch.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am 24.1.2018 um 18:24 schrieb Zer0Cool:

Der Trigger stellt sicher, daß nur 1 Zustandswechsel erfolgt. Bei Bool kann es dir passieren (je nachdem wie man die Transitionen setzt), daß mehrere Übergange erfolgen.


Zustand A  -> (isB == true) -> Zustand B -> irgendwas -> Zustand C
Zustand A  <- irgendwas <- Zustand C

Code:
- isB = true
=> wechselt nach B
- irgendwas 
=> wechselt nach C
- irgendwas 
=> wechselt nach A
=> wechselt nach B (ggf. ungewollter Zustandsübergang)

*irgendwas
 Steht für eine beliebige Bedingung die einen Zustandswechsel erzeugt

 

Aber wenn ich nun nicht weiß welcher Zustand aktiv ist, muss ich da nun mit Bedingungen abfragen welcher aktiv ist?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Naja, entweder man kennt den aktuellen Zustand des Animators oder man muss ihn abfragen. Das Abfragen würde ich aber möglichst vermeiden, da dies wieder Performance kostet, zudem ist es auch nicht gerade einfach. Und nein, über die Bedingungen kannst du den aktuellen Zustand des Animators nicht abfragen. Es gibt Klassen und Methoden des Animators über die du den aktuellen Zustand ermitteln kannst ("AnimatorState"). Zusätzlich kann man eigene Klassen an einen Zustand "pinnen" ("State Machine Behaviours" - diese geben dann wieder Auskunft) oder man kann auch Animationsevents verwenden. Am besten ist natürlich, man kommt ohne ein Nachfragen beim Animator aus und hält sich den angeforderten Zustand des Animator in seiner eigenen Klasse vor. Man geht dann davon aus, daß der Animator auch in den angeforderten Zustand wechselt. Die Schwachstelle hierbei ist nur, man weiß dadurch nicht genau, ob er einen Zustand ggf. wieder verlässt (siehe Beispiel oben).

Was ich gerne hätte, wäre über einen Zustandswechsel des Animators mit einem Event informiert zu werden, aber ich habe nichts in dieser Richtung gefunden.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also wäre so etwas hier eher falsch:

public void AnimatorBewegung(int spielGeschwindigkeit) {
        if(!steuerungDeaktiviert & !charakterTod) {
            switch (spielGeschwindigkeit) {
                case 0:
                    animator.SetBool("isIdle", true);
                    animator.SetBool("crippled", false);
                    animator.SetBool("isRun", false);
                    animator.SetBool("isJump", false);
                    animator.SetBool("isDeath", false);
                    break;
                case 1:
                    animator.SetBool("isIdle", false);
                    animator.SetBool("crippled", true);
                    animator.SetBool("isRun", false);
                    break;
                case 2:
                    animator.SetBool("isIdle", false);
                    animator.SetBool("crippled", false);
                    animator.SetBool("isRun", true);
                    break;
            }
        }
    }

Mein Charakter kann drei Zustände haben:

1. Er steht da.

2. Er Läuft.

3. Er rennt.

Wenn der Spieler nun ein Reset der Spielfläche ausführt oder die Geschwindigkeit ändert (case 1 zu 2 oder 2 zu 1) wird diese Methode aufgerufen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...