Hallo! Wir bei Playrix haben uns für
unsere Unity3D entschieden . Und da ist Animator. In diesem Artikel werde ich Ihnen erzählen, wie wir es zu Hause gemacht haben und wie es funktioniert.
Als wir anfingen, die Architektur unserer Animationsgraphen zu entwerfen, haben wir uns natürlich auch andere Analoga angesehen, insbesondere Unity Animator. Wir wollten jedoch eine universellere Lösung finden. Im Gegensatz zu derselben Unity können wir Animationszustände über die Controller-Oberfläche anpassen. Aber zuerst lohnt es sich herauszufinden, was ein animiertes Zustandsdiagramm ist. Wenn Sie dies bereits festgestellt haben, ist es sinnvoll, den Einführungsteil zu überspringen und mit den Implementierungsfunktionen fortzufahren.
Was genau ist dieses animierte Zustandsdiagramm?
Mit einem Animationszustandsdiagramm können Sie Übergänge zwischen verschiedenen Animationszuständen grafisch darstellen.
Nehmen Sie zum Beispiel die Charakteranimation:
Wir haben ein dreidimensionales Modell eines Mannes und es gibt mehrere seiner Animationen:
- untätig - steht still;
- gehen - geht vorwärts;
- sitzen
- hallo - winkt mit der hand
Der klassische Ansatz zum Verwalten von Animationen lautet wie folgt: Wenn Sie möchten, dass das Objekt steht - im Leerlauf einschalten, gehen - gehen, sitzen - sitzen. Damit sind jedoch gewisse Schwierigkeiten verbunden.
Zunächst müssen Sie die Dauer und Reihenfolge der Animationen manuell steuern. Damit sich eine Person beispielsweise hinsetzen kann, müssen Sie zuerst die Animation abspielen, wie sie sich hinsetzt, und dann die geloopte Animation abspielen, in der die Person bereits sitzt. Das Anpassen der Gelenke dieser Animationen im Code ist schwierig und unpraktisch.
Zweitens machen sich die Verbindungen zwischen Animationen bemerkbar, wenn die Enden der Animation nicht übereinstimmen oder wir eine andere Animation in die Mitte der aktuellen einfügen müssen. In diesem Fall ist es einfach unmöglich, die Animationen perfekt abzugleichen. Erinnern Sie sich an die alten Spiele, in denen Charakteranimationen sofort gewechselt wurden.
Das Animationsdiagramm soll diese Probleme lösen. Damit müssen Sie Animationen nicht manuell bedienen, jetzt arbeiten Sie mit Zuständen. Wie ein Objekt animiert wird, um diesen Zustand zu erreichen, ist die Arbeit von Animatoren und Designern. Jetzt denkt der Programmierer nicht mehr über das Timing und die Reihenfolge der Animation nach, sondern gibt nur noch an, in welchen Zustand das Objekt gehen soll.
Mit dem Animationsdiagramm verschwindet auch das Problem des Zusammenfügens von Animationen. Beim Übergang zwischen Zuständen können wir einen reibungslosen Übergang von einer Animation zu einer anderen vornehmen. Dies geschieht mit Gewichten. Das Gewicht ist ein Mischungsfaktor von 0 bis 1, wobei 0 bedeutet, dass die Animation das Objekt in keiner Weise beeinflusst und 1 es vollständig beeinflusst.
Zum Beispiel ist der Übergang zwischen Gehen (Leerlauf) und Stehen (Leerlauf) sehr anspruchsvoll für die Einrichtung des Prozesses. An jedem Punkt der Laufanimation kann der Charakter anhalten. Daher erfolgt der Übergang nicht sofort, sondern für einen kurzen Zeitraum. Zu diesem Zeitpunkt nimmt das Gehgewicht von 1 auf 0 ab und das Stehgewicht steigt von 0 auf 1. Es ist wichtig, dass die Summe der Gewichte gleich eins ist, da sonst Artefakte auftreten können.
Wie funktioniert das alles?
Ein Graph besteht aus Zuständen und Übergängen. Ein Status ist eine Reihe von Animationscontrollern, von denen jeder eine Art Animation auf einem Objekt abspielen oder eine Art Logik ausführen kann. Der Controller verfügt über Ein- und Ausstiegspunkte. Dies sind die Momente, in denen der Graph den Status mit diesem Controller einschaltet und entsprechend ausschaltet. Der Controller verfügt auch über eine Aktualisierungsfunktion, bei der zusätzlich zum Zeitintervall vom letzten Frame das Gewicht des Übergangs kommt. Um Animationen zu mischen, muss dies berücksichtigt werden.
Controller haben eine einzige Schnittstelle. Darüber hinaus können Entwickler ihre Controller hinzufügen. Sie können beispielsweise einen Controller erstellen, der eine Logik ausführt oder Text in einem Popup usw. festlegt. Diese einfache Anpassung ermöglicht es Ihnen, das Animationsdiagramm sehr flexibel zu verwenden.
Wir haben auch Variablen. Diese Variablen können extern festgelegt werden, auch aus Code, und dann in Controllern gelesen werden. So können Sie beispielsweise eine Art Animation für einen Charakter im selben Status wechseln. Im Allgemeinen können Sie sogar das Paradigma des Übergangs zwischen Zuständen durch Variablen und Bedingungen wie Einheit wiederholen. In Verbindung mit anpassbaren Controllern ist dies recht praktisch.
Übergänge können eine beliebige Anzahl sein. Viele Übergänge können auf die gleiche Weise unbegrenzt in den Zustand versetzt und beendet werden. Übergänge bestimmen die Möglichkeit, Zustände zu erreichen. Wenn es beispielsweise keinen direkten Übergang zwischen den Zuständen A und F gibt, sondern eine Kette A → B → C → D → E → F, wird der Graph selbst verstehen, wenn er einen Übergang von A nach F anfordert, dass er die Zwischenzustände B, C, D durchlaufen muss und E.
Übergänge haben Startintervalleinstellungen und -dauern. Mit der Dauer ist alles einfach - dies ist die Zeit, für die der Übergang erfolgen wird. Das Intervall ist jedoch bereits komplizierter: Es bestimmt den akzeptablen Zeitraum für die Animation, in dem der Übergang gestartet werden kann.
Damit sich ein Charakter beispielsweise hinsetzen kann, müssen Sie zuerst die Animation abspielen, während er sich hinsetzt, und dann die Sitzanimation starten. In diesem Fall sollte das Übergangsintervall von "setzt sich" zu "sitzt" am Ende der Animation "setzt sich" befinden, damit wir sehen können, wie es sich setzt, und dann am Ende schnell, aber reibungslos in die Animation des Sitzes einsteigen.
Ein weiteres Beispiel: Ein Charakter geht und muss anhalten. In diesem Fall sollte das Übergangsstartintervall die gesamte Länge der Animation betragen, da der Charakter jederzeit anhalten kann.
Das Animationsdiagramm erledigt alle damit verbundenen Arbeiten:
- plant einen Weg zum notwendigen Staat;
- Aktualisiert die aktuell ausgeführten Status
- macht einen reibungslosen Übergang zwischen Staaten;
- passt die Gewichte in ihnen an.
Interessante Features
Es gibt viele verschiedene Arten von Animationen in der Playrix-Engine: 3D-Modelle, Wirbelsäule, Blitz, Partikeleffekte, Skelettanimation. Jeder Typ hat einen bestimmten Controller.
Zusätzlich zu einfachen Animationscontrollern haben wir mehrere zusätzliche. Zum Beispiel ein randomisierter Controller. Es kann eine Liste anderer Controller und die Wahrscheinlichkeit ihrer Wahl enthalten. Jedes Mal, wenn ein Objekt mit einem solchen zufälligen Controller in einen Zustand eintritt, erfolgt eine zufällige Auswahl unter Berücksichtigung der Wahrscheinlichkeiten, und der ausgewählte Controller beginnt zu funktionieren. Der Rest schläft und ist inaktiv und wartet auf ihren Moment.
Aber manchmal müssen wir in einem Zustand die Animationen wechseln. Zum Beispiel, wenn mehrere Charaktere das gleiche Diagramm haben und alle eine Art Aktionsanimation haben. Ein Charakter muss seinen Besen holen und sich rächen, ein anderer seine Kamera und Fotos machen, der dritte isst Eis. Für solche Situationen gibt es einen speziellen Controller, der auch eine Liste von Controllern enthält, aber im Gegensatz zu zufälligen hier einen Controller abhängig von der Variablen auswählt.
Variablen werden im Diagramm festgelegt und können extern geändert werden, beispielsweise aus Code. In diesem Beispiel wird ein Zeichenfolgentyp verwendet, und jeder Aktionstyp entspricht einem bestimmten Wert der Variablen. Wenn ein Charakter im Spiel erstellt wird, wird diese Variable je nach gewünschtem Verhalten für ihn festgelegt.
Wir haben auch einen Controller, der mehrere Animationen mischen kann. Sie können beispielsweise Lauf-, Links-, Rechts- und Vorwärtsanimationen mischen. So können Sie bei Kurvenfahrten die Gewichte zwischen ihnen so einstellen, dass die Beine des Charakters nicht verrutschen und das Gehen natürlich aussieht.
Wir müssen tiefer gehen
Die Tatsache, dass wir unsere Einheit bilden, hat viele Vorteile. Eine davon ist, dass wir tun können, was wir wollen und was wir wollen. Und wir wollten eine unbegrenzte Möglichkeit, das Animationsdiagramm zu erweitern.
Wir haben eine Controller-Schnittstelle, es gibt mehrere Controller "out of the box" und es gibt die Möglichkeit, die Schnittstelle zu implementieren und alles darin zu tun (und nicht unbedingt eine Animation):
- Ändern Sie den Text auf der Schaltfläche.
- mit anderen Objekten in der Hierarchie interagieren;
- und sogar ein anderes Animationsdiagramm verwalten.
Diesen Ansatz haben wir bei Besuchern des Zoos im Spiel Wildscapes angewendet. Jeder Besucher hat zwei Diagramme: eines zur Animation des Modells, das andere zur Animation des Verhaltens.
Das erste Diagramm ist recht einfach, es steuert das Gehen und kann einige separate Charakteranimationen abspielen.
Das zweite Diagramm ist viel komplizierter und enthält einige Verhaltensszenarien. Zum Beispiel geht der Charakter zuerst, setzt sich dann auf eine Bank, begrüßt jemanden, macht Fotos und geht weiter. Dies ist ein separater staatlicher Zweig.
Diese Logik könnte in die erste Spalte eingefügt werden, aber dann würden die Animationen viele Male dupliziert. Aber mit zwei Grafiken ist alles viel einfacher. Das Kontrolldiagramm enthält eine Kette von Zuständen, einschließlich der Zustände aus dem ersten Diagramm, das parallel ausgeführt wird.
Was weiter?
Unser Diagramm weiß bereits viel, aber es gibt noch viel Raum für Entwicklung. Die Pläne sehen eine Gruppierung mehrerer Staaten mit Verschachtelung vor. Dies wird die Questspalten erheblich vereinfachen. Die Pläne beinhalten auch Arbeiten zur Verbesserung der Anzeige von Grafiken und Links. Jetzt ähneln die Verbindungen in großen Diagrammen Spaghetti (selbst die Farbe ist ähnlich), und manchmal ist es leicht, verwirrt zu werden.