Space Engineers

Space Engineers

Not enough ratings
Official: Animation system and its modding (Update 01.134)
By Drui and 1 collaborators
Our animation system is currently composed of three parts: state machines, animation trees and layers. Together they make up the animation controller.
Because the whole system is complex, editing data files by hand would be really hard. Therefore we developed the Animation Controller Editor, which allows you to create animation controllers in a graphical user interface and even debug them live in the game.
 
Rate  
Favorite
Favorited
Unfavorite
Difference from the old system
The old system maps animations from Animations.sbc to characters, and mappings are stored along with the character definition. Each animation was then triggered manually in the program. This brings about two main problems:
  • Artists have almost no control over animation or its sequencing, and a programmer can interrupt it at any moment.
  • Manual triggering is complicated for programmers, as they have to catch all the events and check for all the conditions themselves.
The new system is different. The animation controller attached to character lives its own life and switches animations according to inputs provided from the game. The first type of input is variable, for example, the current speed of the character. The second type is action, for example, “character” jumped. Notice that there is no explicit definition for what the change of variable or the triggered action should do. This is specified in the controller and can be even completely ignored. It’s up to the animator.
State machines
The interface of the animation controller editor consists of two tabs. The first one is for state machine editing (see the picture below). The biggest part of the window is occupied by visualization of the selected state machine. A user can add, connect or delete states. You can select a different state machine in the right menu. Properties of any selected object can be modified in the bottom-right list.



The state machine contains all possible animation states and transitions between them. An animation state represents the current state of the character, for example “Standing” or “Running”. States are then connected by transitions. If the condition specified in the transition is satisfied and the transition leads from current state, the animation controller follows the transition to the next animation state (transitions are described below).

Addition and removal of states is done through the top toolbar menu. After selecting the state, you can change its properties in the bottom-right corner. There are these important properties:
  • Name - here you can rename the selected node
  • Type - there are several types of nodes:
    Normal: provides standard behavior (plays the animation).
    Pass: State machine will try to advance immediately to next node when reaching this node. “Pass” node has grey color.
    Any: This node represents virtually any node in the state machine. For example, making connection from node of type “any” will create connection from all nodes inside state machine. This saves lot of work and improves readability of the state machine. “Any” node has purple color.
    Any except target: Only difference is that connection is created from all nodes of state machine except target node of transition.

Transitions and conditions
Transitions are then added by dragging from the dot placed on the right side of the state to another state.


Single clicking on any object displays its properties in the bottom-right corner (transition time between animations, synchronization options). Double-clicking on a transition opens the window for condition editing (see the picture below).



If any condition from the left menu is fulfilled, the transition is performed. The condition can be edited in the right view once selected. It can be composed of particular conditions which need to be fulfilled all at the same time. This OR-AND mechanism allows us to implement any complicated condition.
The picture shows the condition that is fulfilled if @animationfinished equals 1 or speed is greater than 0.3.

Condition hierarchy can be also represented by the picture below. If condition 1,2 is selected in the left list, the right list shows its parts: condition 1 and condition 2.



Property editor provides editing for a particular condition. Select the operator and fill in compared values (the left and right sides of comparison). The values can be either numbers or the name of the connected input variable. A list of all possible variables can be accessed by clicking on the three dots button that appears after clicking on the variable field.
Animation tree
The new animation system still uses MWM animation files as its building blocks. Each animation state contains an animation tree. The picture below shows the animation tree tab. The right list contains all animation states of every machine in this controller, and the left view displays the animation tree for the currently selected animation state.



There are three types of nodes in the animation tree.
  1. Root node - The first one is a root which represents the animation state. This one cannot be deleted, but serves as a “starting point”. You can also use it to navigate back to the state machine by double-clicking.
  2. Track node - This node plays the MWM animation file. You can select whether the animation should loop after finishing, change the playing speed or display info about MWM here.
  3. Mix node - Mixes connected animations according to parameter value. You can set how many animations will be mixed. This will change the number of connectors on the right side of the node. Example: In the picture, if the turning speed is 7.5, both crouchidle and crouch_rightturn will be played and mixed with the same weight.
Layers
The layers in the animation system are similar to layers in picture editors. Each layer can override or add results coming from a previous layer. Layers are evaluated from top to bottom.
It is very important to set initial node of the layer in its properties, otherwise underlying state machine would remain uninitialized.
Modding
  1. Create the following directory structure.
    Name-of-your-mod (create file named ‘contentfolder’ here) - Data - AnimationControllers (save your animation controller here) - Models - Characters - Animations (place your own MWM files here)

  2. Create your animation controller and set its name (using the button in the top toolbar) to match the original animation controller name. For the astronaut, it is ‘Default_Astronaut’. It must match exactly; otherwise, the game does not connect it to the character.
  3. Create your animation state machines and layers using the shortcut of the mod name in their names as a prefix. This will prevent collision with other mods.
  4. Your layers are added on top of existing original layers.
  5. Debug your mod live and you are ready to release!
Tips:
- ModAPI: Method IMyCharacter.TriggerAnimationEvent was added. You can now trigger animation events from your code.
- You can open original animation controller files to learn. You can find them in the folder Content/Data/AnimationControllers.
Live debugging
The editor supports live debugging of the animation controller in the game.
  1. Launch the game and play for the character you want to mod.
  2. Launch the editor and load your animation controller.
  3. The editor will connect to the game automatically.
From this point, every animation state change in the game will be shown in the editor (marking the current state with green color). If you save the controller, it will be updated into the game.

< >
10 Comments
Sieyono May 17, 2016 @ 2:00am 
neat
Capac Amaru May 14, 2016 @ 1:00am 
I'm really excited about the potential of this for my machinima series... but I'm not sure where to begin.

I really wish there were some kind of step by step guide through the process. :steamsad:
Digi May 13, 2016 @ 10:24pm 
Oh and one annoying issue, you can't select animation files that aren't in the game content folder, so I had to copy my animations in the game's folder just to be able to select them in the editor.
Digi May 13, 2016 @ 9:03pm 
Well seems that MySkinnedEntity.AnimationController.Variables. is not allowed in scripts, so there goes using that.
Digi May 13, 2016 @ 7:58pm 
Also some other things I experienced (copy paste from my stored text here):

- the "initial node" in the layer properties defines the entry point SM node
- the IMyCharacter.TriggerCharacterAnimationEvent() method calls transition names and the names must be all lowercase no matter what case they are in the definition
- BoneMask in the layer properties defines what bones are used in the animation, the list is populated once you load an animation file in any node
- game doesn't reload changes made to the vanilla definitions without a full game restart
- mod definitions can't use animation files from the game content without copying them to the mod folder, error: http://pastebin.com/raw/HjzWJBgP
Digi May 13, 2016 @ 7:55pm 
If a transition has a condition it will wait until that condition is true, if you want to do the animation and return you make a transition towards that element then back, on the way towards there you define what condition it triggers on and on the way back you can set "@animationfinished >= 1", the variables are accessible in the editor and I believe you can add more and add/set variables in the modAPI, not entirely sure as I didn't test it ingame.

I have no idea what the time is supposed to do but for me it doesn't do a smooth transition, it instantly goes to the idle animation regardless of time, however time does affect the re-trigger of that animation which is weird: https://www.youtube.com/watch?v=amm0J8sdEmc
Digi May 13, 2016 @ 7:55pm 
Bone mask is the bones that are affected by the layer, if your animation animates the entire character but you only want the arms to animate then add only the arms to the bone mask.

And transitions... well, seems like "pass" is totally useless since a node will immediately go to another node if it has a transition with no name and no condition.
If a transition has a name it will wait until it's manually triggered (by IMyCharacter.TriggerAnimationEvent(), since that method seems to be able to only trigger transition names).

(man this is a long comment, continuation next comment again...)
Digi May 13, 2016 @ 7:55pm 
This is all things that I've found so far while messing around with it:

If you give it the subtypeId of an existing character (like "Default_Astronaut") it will append things to that character.
However, there are some cases where the entire animation controller is replaced for some reason, like when I added my modded controller next to the game's vanilla controller in the same folder, resulted in this: https://www.youtube.com/watch?v=jHqk6IUBui4 :))

I suspect layers and statemachines can be overwritten if they have the same name, that's why they say to have an unique name for our own.

Also, layer's "add" or "replace" states what it does to the bones, not what it does to the layer.
I had it on add and it did a mix of the idle animation and my animation, most of the time you'd want that on replace.

(continuation next comment...)
Harag May 13, 2016 @ 5:05pm 
Some more situations we could use examples for:
- How is a transition "performed"? Is it immediate? If not, what's the meaning of labels like "0.25s" and when does the animation of the target state start to play? What does happen to the animation of the current animation state? Is there some form of automatic cross-fade? If yes, what do we do if that looks ugly?
- Why is it useful to have a "pass" node?
- When is it appropriate to use an "any" state, when an "any except target" state?
- When is it useful to create a "submachine state" (there's a button for it)?
- Are Layers not editable via the AC editor? How exactly does a layer "add" to a layer below? Also, the meaning of <BoneMask> isn't explained at all.
Harag May 13, 2016 @ 4:26pm 
In "Modding": What does "connect it to the character" mean? Will a modded animation controller be added to the game's animation controller or will it replace the original? How are we supposed to add a new gesture like we could before (including the toolbar icon to trigger it)? I think an example would be very helpful.