Animation synchronisation
Unit animations sometimes need to be synchronised with two things: gameplay events, and sound effects. There are three main categories:
Animation synced only with sound effect
Typically gather, build.
The animation plays back at 30fps, multiplied by the "speed" percentage defined in the actor XML file (100 = original speed, 200 = twice as fast, etc), sometimes multiplied by a gameplay speed factor (usually 1.0, i.e. no change, but an elite unit might build a little bit faster).
A sound effect plays at the "event" point defined in the actor XML file (a fraction through the animation: 0.0 = at the start of the animation, 0.5 = in the middle, 1.0 = at the end, etc) - this should be the point where the axe/hammer/etc hits the tree/building/etc.
The animation speed is completely unrelated to the gameplay - the unit will gather/build/etc at a constant rate regardless of the animation, so the rates can be tweaked independently. The animation loops when it reaches the end.
Animation synced with nothing
Typically idle, walk, run, death.
Like the previous one, but without even the sound effect. The actor XML doesn't need to define an "event".
For walk and run, the gameplay speed factor is much larger than 1.0: it is equal to the movement speed of the entity, which is typically around 7.0 for walking and 12.0 for running but may vary widely for different units. This means the actor XML file must divide the speed by this factor (e.g. set speed=15 for the walk animation), so that the final multiplied speed is close to the desired animation speed.
Animation synced with gameplay
Typically attack.
The gameplay code determines how long the animation will take (e.g. if an archer shoots every 2 seconds, its attack animation will be stretched or squashed to take exactly 2 seconds). The speed defined in the actor XML is completely ignored. The animation playback is offset so that the gameplay event (e.g. the projectile launch) occurs precisely at the "event" point during the animation. The entity definition and animation file need to be carefully coordinated so the speed and offset looks good.
A sound effect plays at "event", as before. Also, if there is an ammunition prop then it is hidden at the "event" point, and made visible again at the "load" point (a fraction through the animation, defined in the actor XML). An ammunition prop is one that's attached to a prop point called loaded-r_hand (or loaded- with any other valid prop point instead of r_hand). It doesn't matter if "load" comes before or after "event". This should be used for units that release a projectile, and then load a new one during their animation cycle.
How to tweak animation speeds
Some general guidelines:
The Actor Viewer is the easiest way to test animations. Tell it to display an entity which uses the actor you're testing, and it will pick up the entity's movement speed and attack speed. Use the "Slow" mode to get the synchronisation more precise. If you edit and save an actor XML file while viewing the unit, it should be automatically reloaded and displayed. (If that doesn't work (e.g. I think it's broken if you modify a rider actor), just select a different unit in the list on the left and then go back to the original and it should be okay.)
Editing XML files in a text editor might be easier than using the Actor Editor, since then you can e.g. comment out chunks of the file that you don't want to test.
- idle, death, gather_(fruit|grain|meat): Adjust the speed attribute to control the speed. (Death animations are looped in the Actor Viewer, but will only be played once in the game. The last frame will be used for corpses.)
- walk, run: Adjust the speed attribute. This should probably be chosen so there's not much foot sliding - use the Actor Viewer's "Move" button to see it in context. The speed will also be affected by the
<UnitMotion>
in the entity template XML file (in themods/public/simulation/templates/
directory) - changing the unit's movement speed will change the animation speed (so the stride length will stay the same).
- gather_(metal|stone|wood), build: Adjust speed. Set the event attribute to a fraction in the range 0.0 .. 1.0, to indicate where the tool hits the target - the sound will play at this point. Sounds are defined in the corresponding entity template XML files. Currently there's only a single event point - tough luck if you want two in a single animation (like some of the wood-chops).
- Melee attack: The speed is determined entirely by the
<Attack>
component's<RepeatTime>
in the entity XML. Ignore the speed in the actor. If necessary, adjust the entity speed so the animation looks okay (but this has an effect on gameplay too). Set the event attribute to a fraction, so it matches where the enemy is contacted - the sound will play at this point and the target will be hurt.
- Ranged attack: Similar to melee. Put a prop on loaded-r_hand (or any loaded-) for the held projectile. Put a prop on projectile to define what the launched projectile will look like. Set event to a fraction that matches where the projectile is released (the loaded- prop will be hidden). Set the load attribute to a fraction where the loaded- prop will be made visible again.
- Cavalry, chariots: Put the event and projectile things on the rider actor, not on the base horse actor. The horse shouldn't use any event at all (else it will get synchronised when it shouldn't).