All angles in the AnimGraph that represent a direction or heading are in degrees, and relative to the character. For example, a heading of 0 always means the current forward direction of the character. Positive angles are to the left, negative to the right.
AnimGraph Nodes have the ability to be reset during runtime, which means that they should snap back to their starting configuration. For example, if an Animation Clip node gets reset it will jump back to the first frame of its animation. Resetting a state machine will cause it to make its Start State the active state, even if there is no transition connecting it to the current state.
Each node in the graph has the ability to "Reset" any of its children, and managing resets is an important part of getting the correct behavior and avoiding pops in the resulting animation. In general, you do not want to reset a node that was active during the last update because doing so will likely cause a large sudden change in the resulting pose. But you generally do want to reset nodes that when nodes become active, because otherwise they make have been left in an undesirable state.
When in Preview mode or viewing a replay, nodes will flash orange when they are reset.
Graphs can have any number of parameters, which are values that the game feeds to the graph to allow it to make decisions about what animations to play. Unlike the fields in the Main Inputs panel, parameters are specific to that graph. These can be things like whether or not to crouch, the character's current health, or which weapon the character is holding.
Parameters are typed, and the type dictates the ways that they can be used:
- Bool Parameters can either be on or off. Good for status that can be toggled
- Enum Parameters can be one of serveral user-defined values, each of which can have a name associated with it. For example, a weapon enum might have values of knife, pistol, rifle or shotgun. While Enum parameters are similar to Int parameters, the fact that they can only have a limited number of values and those values have names that are used throughout the editor make them less error prone than always having to remember that, for example, a value of 2 means rifle.
- Int Parameters can be any whole number
- Float Parameters can be any fractional number
- Vector Parameters consist of 3 floats
AnimTags are an improvement on AnimEvents from the previous animation system, and are the preferred method of notifying game code that a certain event has happened. While AnimEvents are still supported by AnimGraph for compatibility, Tags offer several benefits:
- Tags can have a duration. Listeners will receive tag notifications in Start/End pairs, or as "fired" which means that it had no duration. With animevents it was possible to create begin/end pairs on an animation, but if the animation is interrupted before it reaches the end event then the game code can get stuck waiting forever. Tags that have started is guaranteed to send an ended notification, even if they are interrupted. They will also get automatically merged, so if one animation has a tag at the end and another has the same tag at the start, then the game code will only see 1 start/end pair instead of 2. Tags can also be put on items other than animations, such as state in the State Machine node.
- Tags are typed. AnimEvents differentiated themselves only with an ID, so the game code has to listen for all animevents even if it was only interested in a particular one. With AnimTags, the game code can register to listen for only the types of tags that it cares about. So for example the sound system can register to receive only Audio tags from the graph.
- Tags can have arbitrary payloads. So an Audio tag can have a sound file, and a cloth tag can have settings for the cloth solver. AnimEvents take only a string as a payload, and while that string can be a KV3 description of several settings, the string still has to get parsed into a struct that the code can use
- Tags are data driven. Each graph can define its own set of unique tags without any modification to code. AnimEvents must all have a unique entry in a static list defined in the code. This list has gotten very big as new events have been created over the years, and events that might be unique to one project will still show up in the builds of all the others, leading to leaks about unannounced projects.
Motors are responsible for taking input from the game or user about how the character should move and converting it into a format that the graph can use to drive animation choices. For example, an AI character might use a Path motor, which will take a path from the navigation system and make sure the character moves along that, or a Player Control Motor which will instead use directional inputs like forward, back, left and right. Characters that don't move don't need a motor.
Motors update twice:
- Before the nodes update, so that they can process any input from the game and make it available to the nodes
- After the nodes have finished updating, so that they can perform any necessary fix-up on the root motion calculated during the node update
This is the amount of change in the position of the character in the world that was calculated for the current update. Root motion is calculated as part of the logic update, then passed to the game to check to see if the character hit anything as it moved, so the motion that the graph calculates might not be exactly how the character ends up moving. The nodes in the graph are free to manipulate the root motion as necessary. For example the Animation Clip node will set the root motion based on the root motion data stored in the animation, but the Mover node will procedurally generate root motion to match the target speed set by the motor.
Source 2 uses a client-server architecture, even for single player games. That means the gameplay logic happens on the server, and the results have to be replicated to the client. To keep the performance costs of the server down, it does not update every character every time it ticks: most AI characters only get get updated at about 10fps. So in order to have smooth motion on the client when its rendering at much higher framerates than 10fps, the networking system has to interpolate the data between the ticks of the server. In order to do that the client needs to have the data from two server ticks, so it delays what the player sees of the animation by about 100ms, which gives it time to allow the next tick of data to arrive from the server.
So what does all this mean? Basically for AI and all players except the local player:
- All the logic happens on the server
- AnimGraph parameter values, etc will only get set on the server, not the client. So don't think there's something wrong if do a client animgraph recording and the parameters are not the values you expect
- The AnimGraph on the server will only get updated at 10fps (ie: onces every 100ms)
- So don't make graphs that rely on split second timing in order to look correct
- AnimGraph recordings of the server will look choppy
- The AnimGraph on the client updates every frame
- The motion will still be smooth. The client AnimGraph handles the difference in framerate
- The animation you see on screen is 100ms old
- There are exceptions to this, eg: the VR hands and network-predicted entities like the local player
- AnimGraph takes care of networking its state automatically, so don't worry about it unless you're trying to do something fancy