Utiliser les AnimationTree

Introduction

With AnimationPlayer, Godot has one of the most flexible animation systems that you can find in any game engine. The ability to animate almost any property in any node or resource, as well as having dedicated transform, bezier, function calling, audio and sub-animation tracks, is pretty much unique.

Cependant, la prise en charge de la fusion de ces animations via AnimationPlayer est relativement limitée, car seul un temps de transition de fondu fixe peut être défini.

AnimationTree est un nouveau nœud introduit dans Godot 3.1 pour traiter les transitions avancées. Il remplace l'ancien AnimationTreePlayer, tout en ajoutant un grand nombre de fonctionnalités et de flexibilité.

Créer un AnimationTree

Avant de commencer, il faut préciser qu'un nœud AnimationTree ne contient pas ses propres animations. Il utilise plutôt les animations contenues dans un nœud AnimationPlayer. De cette façon, vous pouvez éditer vos animations (ou les importer depuis une scène 3D) comme d'habitude et ensuite utiliser ce nœud supplémentaire pour contrôler la lecture.

La façon la plus courante d'utiliser AnimationTree est dans une scène 3D. Lorsque vous importez vos scènes à partir d'un format d'échange 3D, elles seront généralement accompagnées d'animations intégrées (soit multiples, soit séparées depuis une grande à l'importation). A la fin, la scène Godot importée contiendra les animations dans un nœud AnimationPlayer.

Comme vous utilisez rarement des scènes importées directement dans Godot (elles sont soit instanciées soit héritées), vous pouvez placer le nœud AnimationTree dans votre nouvelle scène qui contient celle importée. Ensuite, pointez le nœud AnimationTree vers l' AnimationPlayer qui a été créé dans la scène importée.

C'est comme ça que ça se passe dans la démo Third Person Shooter, pour référence :

../../_images/animtree1.png

Une nouvelle scène a été créée pour le joueur avec un KinematicBody comme racine. Dans cette scène, le fichier original .dae (Collada) a été instancié et un nœud AnimationTree a été créé.

Création d'une arborescence

Il y a trois principaux types de nœuds qui peuvent être utilisés dans AnimationTree :

  1. Les nœuds d'animation, qui référencent une animation de l' AnimationTree lié.

  2. Les nœuds racine d'animation, qui sont utilisés pour mélanger les sous-nœuds.

  3. Les nœuds Animation Blend, qui sont utilisés dans AnimationNodeBlendTree comme un seul graphique de mélange via plusieurs ports d'entrée.

Pour définir un nœud racine dans AnimationTree, quelques types sont disponibles :

../../_images/animtree2.png
  • AnimationNodeAnimation : Sélectionne une animation dans la liste et la joue. C'est le nœud racine le plus simple, et généralement pas utilisé directement comme racine.

  • AnimationNodeBlendTree : Contient de nombreux nœuds de type blend, tels que mix, blend2, blend3, one shot, etc. C'est l'une des racines les plus utilisées.

  • AnimationNodeStateMachine : Contient plusieurs nœuds racine en tant qu'enfants dans un graphe. Chaque nœud est utilisé comme un état, et fournit de multiples fonctions pour alterner entre les états.

  • AnimationNodeBlendSpace2D : Permet de placer les nœuds racine dans un espace de mélange 2D. Contrôlez la position du mélange en 2D pour mélanger entre plusieurs animations.

  • AnimationNodeBlendSpace1D : Version simplifiée de ce qui précède (1D).

Arbre de mélange

Un AnimationNodeBlendTree peut contenir à la fois des nœuds racine et des nœuds réguliers utilisés pour le mélange. Les nœuds sont ajoutés au graphique à partir d'un menu :

../../_images/animtree3.png

Tous les arbres de mélange contiennent un nœud Output par défaut, et quelque chose doit y être connecté pour que les animations puissent être jouées.

La manière la plus simple de tester cette fonctionnalité est de lui connecter un nœud Animation directement :

../../_images/animtree4.png

Cela permettra simplement de lire l'animation. Assurez-vous que l' AnimationTree est actif pour que quelque chose se produise réellement.

Voici une brève description des nœuds disponibles :

Blend2 / Blend3

Ces nœuds se mélangent entre deux ou trois entrées par une valeur de mélange spécifiée par l'utilisateur :

../../_images/animtree5.gif

Pour des mélanges plus complexes, il est conseillé d'utiliser des espaces de mélange à la place.

Le mélange peut également utiliser des filtres, c'est-à-dire que vous pouvez contrôler individuellement les pistes qui passent par la fonction de mélange. Ceci est très utile pour superposer des animations les unes sur les autres.

../../_images/animtree6.png

OneShot

Ce nœud exécutera une sous-animation et retourne une fois qu'elle sera terminée. Les temps de mélange pour l'entrée et la sortie peuvent être personnalisés, ainsi que les filtres.

../../_images/animtree6b.gif

Seek

Ce nœud peut être utilisé pour provoquer une commande de recherche sur n'importe quel sous-enfant du graphe d'animation. Utilisez ce type de nœud pour lire une Animation depuis le début ou depuis une certaine position de lecture à l'intérieur de l'AnimationNodeBlendTree.

Après avoir réglé le temps et modifié la lecture de l'animation, le nœud de recherche se met automatiquement en mode veille à la prochaine image du processus en réglant sa valeur seek_position sur -1.0.

# Play child animation from the start.
anim_tree.set("parameters/Seek/seek_position", 0.0)
# Alternative syntax (same result as above).
anim_tree["parameters/Seek/seek_position"] = 0.0

# Play child animation from 12 second timestamp.
anim_tree.set("parameters/Seek/seek_position", 12.0)
# Alternative syntax (same result as above).
anim_tree["parameters/Seek/seek_position"] = 12.0

TimeScale

Permet de mettre à l'échelle la vitesse de l'animation (ou de l'inverser) dans n'importe quel nœud enfant. En le mettant à 0, l'animation sera mise en pause.

Transition

Machine à états très simple (quand vous ne voulez pas gérer un nœud StateMachine). Des animations peuvent être connectées aux sorties et des temps de transition peuvent être spécifiés.

BlendSpace2D

BlendSpace2D est un nœud pour faire des mélanges avancés en deux dimensions. Les points sont ajoutés à un espace bidimensionnel, puis une position peut être contrôlée pour déterminer le mélange :

../../_images/animtree7.gif

Les plages en X et Y peuvent être contrôlées (et étiquetées pour plus de commodité). Par défaut, les points peuvent être placés n'importe où (il suffit de faire un clic droit sur le système de coordonnées ou d'utiliser le bouton ajouter un point) et les triangles seront générés automatiquement à l'aide de Delaunay.

../../_images/animtree8.gif

Il est également possible de dessiner les triangles manuellement en désactivant l'option triangle automatique, bien que cela soit rarement nécessaire :

../../_images/animtree9.png

Enfin, il est possible de changer le mode de mélange. Par défaut, le mélange se fait par interpolation des points à l'intérieur du triangle le plus proche. Lorsque vous traitez des animations 2D (image par image), vous pouvez vouloir passer en mode Discret. Si vous souhaitez conserver la position de lecture actuelle lorsque vous passez d'une animation discrète à une autre, il existe un mode Carry. Ce mode peut être modifié dans le menu Blend :

../../_images/animtree10.png

BlendSpace1D

Ceci est similaire aux espaces de fusion 2D, mais en une seule dimension (donc les triangles ne sont pas nécessaires).

Machine à état

This node acts as a state machine with root nodes as states. Root nodes can be created and connected via lines. States are connected via Transitions, which are connections with special properties. Transitions are uni-directional, but two can be used to connect in both directions.

../../_images/animtree11.gif

There are many types of transition:

../../_images/animtree12.png
  • Immediate : Passera immédiatement à l'état suivant. L'état actuel se terminera et se fondra dans le début du nouveau.

  • Sync : Passera immédiatement à l'état suivant, mais cherchera le nouvel état à la position de lecture de l'ancien état.

  • At End : Attendra la fin de la lecture de l'état actuel, puis passera au début de l'animation de l'état suivant.

Les transitions ont également quelques propriétés. Cliquez sur n'importe quelle transition et elle sera affichée dans le dock de l'inspecteur :

../../_images/animtree13.png
  • Switch Mode est le type de transition (voir ci-dessus), il peut être modifié après la création ici.

  • Auto Advance activera automatiquement la transition lorsque cet état sera atteint. Cela fonctionne mieux avec le mode de commutation At End.

  • Advance Condition activera l'avance automatique lorsque cette condition est définie. Il s'agit d'une zone de texte personnalisée qui peut être remplie avec un nom de variable. La variable peut être modifiée à partir du code (nous y reviendrons plus tard).

  • Xfade Time est le temps de fondu enchaîné entre cet état et le suivant.

  • Priority is used together with the travel() function from code (more on this later). Lower priority transitions are preferred when travelling through the tree.

  • Disabled toggles disabling this transition (when disabled, it will not be used during travel or auto advance).

Racine de mouvement

Lorsque vous travaillez avec des animations 3D, une technique populaire consiste pour les animateurs à utiliser l'os du squelette racine pour donner du mouvement au reste du squelette. Cela permet d'animer des personnages d'une manière où les pas correspondent réellement au sol en-dessous. Il permet également une interaction précise avec les objets lors des cinématiques.

Lors de la lecture de l'animation dans Godot, il est possible de sélectionner cet os comme piste de mouvement racine. Ce faisant, la transformation de l'os sera annulée visuellement (l'animation restera en place).

../../_images/animtree14.png

Ensuite, le mouvement réel peut être récupéré via l'API AnimationTree comme une transformation :

anim_tree.get_root_motion_transform()

Ceci peut être fourni à des fonctions telles que KinematicBody.move_and_slide pour contrôler le mouvement des personnages.

There is also a tool node, RootMotionView, that can be placed in a scene and will act as a custom floor for your character and animations (this node is disabled by default during the game).

../../_images/animtree15.gif

Contrôle depuis le code

Après avoir construit l'arbre et l'avoir prévisualisé, la seule question qui reste est "Comment tout cela est-il contrôlé depuis le code ?".

Keep in mind that the animation nodes are just resources and, as such, they are shared between all instances using them. Setting values in the nodes directly will affect all instances of the scene that uses this AnimationTree. This is generally undesirable, but does have some cool use cases, e.g. you can copy and paste parts of your animation tree, or reuse nodes with a complex layout (such as a state machine or blend space) in different animation trees.

Les données d'animation actuelles sont contenues dans le nœud AnimationTree et sont accessibles via les propriétés. Consultez la section "Paramètres" du nœud AnimationTree pour voir tous les paramètres qui peuvent être modifiés en temps réel :

../../_images/animtree16.png

Ceci est pratique car il permet de les animer à partir d'un AnimationPlayer, ou même de l' AnimationTree lui-même, permettant la réalisation d'une logique d'animation très complexe.

Pour modifier ces valeurs à partir du code, il faut obtenir le chemin de la propriété. Cela se fait facilement en passant la souris sur l'un des paramètres :

../../_images/animtree17.png

Ce qui permet de les régler ou de les lire :

anim_tree.set("parameters/eye_blend/blend_amount", 1.0)
# Simpler alternative form:
anim_tree["parameters/eye_blend/blend_amount"] = 1.0

Voyage de la machine à état

One of the nice features in Godot's StateMachine implementation is the ability to travel. The graph can be instructed to go from the current state to another one, while visiting all the intermediate ones. This is done via the A* algorithm. In the absence of any viable set of transitions starting at the current state and finishing at the destination state, the graph teleports to the destination state.

Pour utiliser la capacité de déplacement, vous devez d'abord récupérer l'objet AnimationNodeStateMachinePlayback du nœud AnimationTree (il est exporté comme une propriété).

var state_machine = anim_tree["parameters/playback"]

Une fois récupéré, il peut être utilisé en appelant l'une des nombreuses fonctions qu'il offre :

state_machine.travel("SomeState")

La machine à états doit être en cours d'exécution avant que vous puissiez voyager. Assurez-vous d'appeler start() ou de choisir un nœud pour Jouer automatiquement au chargement.

../../_images/animtree18.png