S2ENGINE HD  1.4.6
Official manual about S2Engine HD editor and programming
Animations

Animation Blending

In S2ENGINE HD animations are always blended together, using weighted interpolations. The result of blending interpolation is a new animation that contains a percetage of every blended animation, basing on its weight. The weight of an animation can have values from 0.0 to infinite. This means that, given a set of two or more animations, more big is the weight of an animation more this animation will influence the final result.

AnimationCrossFade function can be used to smoothly play transition between animations in a given time interval. In other words, when applying CrossFade of an animation, its weight is gradually brought to 1.0 value while all other animations weights are gradually brought to 0.0 value.

1D/2D Blended animations

From version 1.4.6 there are two new type of animation: 1D and 2D blended animation.

1D blended animation

It is an animation that blends two or more source animations basing on a single float parameter. The float parameter values can range from 0 to 1. 0 value means the first animation source completely visible and all others completely invisible, value 1 means the last animation source completely visible and all others completely invisible.
Source animations are equally distributed along the float parameter values intervall, for example if you have 3 source animations the first animation blends from 0 to 0.5, the last from 0.5 to 1.0 and the middle animation reaches maximum value in 0.5 and minimums in 0 and 1, as showed into the following image:

blend1d.jpg

This type of animation is useful if you want to blend animations basing on a single value, for example imagine you have 3 animations: walk, run, runFast, you can build a 1D Blended animation using these 3 source animations and blend them using as blending value the speed of the character you want to animate.
To assign a value to the 1D blending parameter you can use SetAnimationBlendX function.

2D blended animation

It is an animation that blends four or more source animations basing on two float parameters.

Note
The number of source animations but be a multiple of two.

The float parameters values can range from 0 to 1. In this case source animations are arranged into a table, one parameter controls the blending between columns (X direction), the other controls the blending between rows (Y direction).
To assign a value to the X blending parameter you can use SetAnimationBlendX function, To assign a value to the Y blending parameter you can use SetAnimationBlendY function. As for 1D blended animations the animations are equally distributed along X and Y directions:

blend2d.jpg

In the image above colored dots correspond to animations max values, the arrows are directions in which animation values go from max to min.

See also
ModelScript and Animations to read how to create and edit blended animations.

Animation Channels

Channels are set of blended animations. Each channel is identified by an ID number. When channel plays an animation it plays the result of the blending of all its contained animations. Channels can play animations indipendently but all animations of a single channel are automatically played in sync. This is just due to the fact that channel plays the result of the interpolaion and not the single animations.

Diapositiva1.jpg

Channels are superimposed basing on their ID, from smallest to highest. This means that channel with ID 1 is superimposed to channel ID 0, 2 to 1, 3 to 2 and so on. Like animations also channels are blended but in a bit different way: channel weight go from 0.0 to 1.0 values, and if a channel has weight 1.0 and another channel has weight 1.0, the channel with higher ID wins, completely covering the smaller ID channel.

Diapositiva2.jpg

So if you want a channel appears gradually you have to lowering the weight of the higher channel mantaining to 1.0 the weight of the smaller channel.

Attention
if a channel weight is set to 0.0, the channel animation is not processed.
From version 1.4.6 channels must be explicitly added to the entity to animate using AddAnimationChannel function.
Once you have added a channel you must add the animations you want to play in that channel using AddAnimationToChannel function.

Channel mask

Channels can be maskered. The mask of a channel as the same behaviour of the blending mask of a texture: only the nodes of the channel covered by the mask are updated. This means that, for example, you can apply a mask to the top side of a model and using this mask for a shoot channel of ID 1, playing a channel with ID 0 containing a walk/run animation you can blend it with a shoot channel that works only on the top side of the model: the result is that model can shoot while walking, simply changing the weight of shoot channel.

Diapositiva3.jpg
See also
ModelScript and Animations to know how to create masks, assign animations to a model, and more about editing animations.

Scripting Animations

To better understand these concepts we will show a small tutorial that will let you to test some animation features inside the editor, sending messages to a scripted character. First write the script. Suppose we have a model, for example the marine model, with 4 animations: standby,run,walk and aim. We want our character pass gradually from walk to run animation basing on his velocity and we want he aim while running/walking, or aim when in standby state. Also suppose our character have a mask, named "BodyTop", that mask the top side of out character model. We set 3 channels:

  • standby channel: ID=0, containing only the standby animation
  • walk/run channel: ID=1, containing walk and run animations
  • aim channel: ID=2, containing aim animation and the BodyTop.
/* tell editor what messages we want use */
#message "aim"
#message "move"
#message "no_aim"
#message "standby"
var string state;
var bool shoot;
var int channel0;
var int channel1;
var int channel2;
/* create the 3 needed channels at postInit() time */
function void postInit()
{
/* Add channel 0 */
channel0=AddAnimationChannel();
/* Add channel 1 */
channel1=AddAnimationChannel();
/* Add channel 2 */
channel2=AddAnimationChannel();
/* Add animations to channel0 */
AddAnimationToChannel(channel0,"standby");
/* Add animations to channel1 */
AddAnimationToChannel(channel1,"run");
AddAnimationToChannel(channel1,"walk");
/* Add animations to channel2 */
AddAnimationToChannel(channel2,"aim");
/* blend animation "standby" into channel 0 (standby channel), with a weight of 1.0 */
BlendCurrentAnimation("standby",1.0,0);
/* blend animations "run" with weight 0.0 and "walk" with weight 1.0 into channel 1 */
BlendCurrentAnimation("run",0.0,1);
BlendCurrentAnimation("walk",1.0,1);
/* blend animation "aim" into channel 2 with a weight of 1.0 */
BlendCurrentAnimation("aim",1.0,channel2);
/* set mask for channel2*/
SetAnimationChannelMask(channel2,"BodyTop");
/* Set channel0 weight to 1.0 and channel1,channel12 weights to 0.0 at start */
BlendAnimationChannel(channel0,1.0);
BlendAnimationChannel(channel1,0.0);
BlendAnimationChannel(channel2,0.0);
/* start character state */
state="standby";
/* don't aim at start */
shoot=false;
/* play all animations at start. NOTE that channels 1 and 2 have weight 0.0 so they are not processed. Only standby animation channel works.
Even if they do not work for channels 1,2 We call these functions to make engine plays animations as soon as we set channel weights to a value > 0.0 */
PlayAnimation(channel0,true);
PlayAnimation(channel1,true);
PlayAnimation(channel2,true);
}
/* process messages to test animations, fadeIn, fadeOut channels */
function void message()
{
/* check if the character has received a aim command */
if(ReceivedMessage("aim"))
{
/* play shoot animation by fade in channel2 in 100 milliseconds */
AnimationChannelFadeIn(channel2,100.0);
}
/* check if the character has received a NOT aim command */
if(ReceivedMessage("no_aim"))
{
/* Fade Out channel2 in 100 milliseconds if do not aim */
AnimationChannelFadeOut(channel2,100.0);
}
/* check if the character has received a move command */
if(ReceivedMessage("move"))
{
/* blend animations basing on a velocity value, from 0.0 to 1.0 (message#0) */
var float velocity;
velocity=float(message#0);
/* blend run basing on velocity, 1.0 max velocity (run) */
BlendCurrentAnimation("run",velocity,channel1);
/* if velocity is near 0.0 than character walk */
BlendCurrentAnimation("walk",1.0-velocity,channel1);
/* Fade In channel 1 in 100 milliseconds to pass from standby to walk/run */
AnimationChannelFadeIn(channel1,100.0);
}
/* check if the character has received a standby command */
if(ReceivedMessage("standby"))
{
/* Fade Out channel 1 in 100 milliseconds to pass from walk/run to standby */
AnimationChannelFadeOut(channel1,100.0);
}
}

To test this script open the notepad and copy the script, then save the text file as test_anim.sc2 file.
Open the editor and load The fps.bin file.
Select one marine character and replace his script with test_anim.sc2 script.
Press Recompile check button and then click on Apply button to update the character.
You will see the list of all messages exposed. Select move message and specify the velocity param into params input box, you will see character walk/run basing on param value (from 0.0, walk, to 1.0, run). Select aim message to see character aiming while walking/running, select no_aim message to return to previous state.

AnimTut01.jpg

Animation Keyframes

Animations can have some frames marked as key. You can make this inside the editor. When an animation is performed the animated entity sends a message to itself when a keyframe is reached. The name of the message is: AnimTime. The elements of content of the message are:

  1. name of the playing animation containing the keyframe.
  2. progressive index of the reached keyframe (for example if you have a walk animation at index 0 will be the first step and at index 1 will be the scond step).
  3. the weight of the animation
  4. numer of the playing channel

Then you can process the message inside the Message() function of the script associated to the animated entity.

See also
Edit Animation Keyframes to know how to add/edit keyframes.