Animation State Editor

User-centered tool for creating in-game animation state machines

Since I am passionate about and enjoy creating user-friendly tools for game development, I decided to create an editor for our game animators that vastly speeds up our animation pipeline.

The editor is based on ImGui Node Editor by thedmd, which is a node editor used for visual scripting where Dear ImGui handles the underlying node logic. I also use Dear ImGui to draw the nodes, the node connections (the edges), and all windows related to configuring the graph. Additional rendering, such as the preview window, is through my project groups engine, R.O.S.E.

Video Block
Double-click here to add a video by URL or embed code. Learn more

Connecting nodes is as simple as holding down right click and dragging. The connections also snap to the nearest center of each side to avoid spaghetti.

Features & Development

Connecting animation nodes

I started out working on linking nodes together, since they decide how the graph runs. The links decide the transition time and contain conditions that, when met, trigger a transition.

Each object in the world owns a blackboard — this is what allows us to trigger animations with in-game variables. For example, our object could be a player controller which is currently in a sprinting state. This could be added to its blackboard and read from our graph to trigger a sprinting animation on the player.

When the variable “Walking” equals true, we blend from the Idle animation to the Walk animation.

Video Block
Double-click here to add a video by URL or embed code. Learn more

How animations and transitions work

Every frame we evaluate our current node and iterate over all connections. If we have one or more conditions, we allow a transition only when at least one of these are met. Otherwise we wait until our current animation clip has finished playing and transition afterwards.

Every time we transition, the target node becomes our current node and we set — or blend towards — that nodes animation.

Blending works by decomposing the transform matrix of each animations into the translation, rotation, and scale. These are then lerped (spherically lerped for the rotation quaternion) based on how for along the blend time we are.

Video Block
Double-click here to add a video by URL or embed code. Learn more

Global animation layers

I took inspiration from the Unity Animator Controller for this one: their system contains one base layer and any amount of global layers which are constantly evaluated, and I felt that this method was easy to understand, scalable, and could create powerful layers for ones animation.

In my graph, the user can select a parent joint, a mask ID, as well as exclude mask IDs, which decide which joints are affected by the layer.

When an animation layer is being added to the skeletons base layer, it starts at the selected parent joint before iterating over all its child joints, skipping any joints that aren’t in that layers mask and any joints that are in the exclude mask.

Video Block
Double-click here to add a video by URL or embed code. Learn more

Real time preview, content browser, and other quality of life features

From the very start, I knew I needed the Animation State Editor to feature a real time preview window, to make iterative work that much easier for game animators. The preview window is displayed next to the graph and has features like the Blackboard Testing window, allowing one to test how in-game variables could affect the animations.

To make the preview window work with live updates I update the skeleton and the internal graph system whenever the user changes something in the editor.

Initially, I ran into issues like things not updating correctly or sometimes crashes. After working on the editor for some time, I learned how important it is to have readable and modular code, such that I could add, test, and verify data coming from editor changes without hassle, speeding up the work process significantly once my code was cleaned up.

Conclusion

Future plans

I intend to keep working on Animation State Editor until my time at The Game Assembly comes to an end, as I hope it’s a useful tool for game project 8. I plan on adding support for 2D blend spaces as well as having more extensive testing and feedback sessions with our game animators once the development of our next game project starts.

What I learned

I never expected this journey to be as helpful for me as it was. Working on and designing Animation State Editor gave me a lot of insight on usability, quality of life, and the importance of feedback from the target audience.

I also learned how to plan and set goals for myself; almost all of my agile development and planning has been in the context of game projects done in groups, but now I got to teach myself about setting a path for an individual passion project, from which I learned my own pace and limits.