Animation and Stance
It takes about 15 minutes to read this article
This article provides an overview of what animation is, what stance is, the default stance for character , and how to use animation and stance.
Definition of animation and stance
Animation Definition
Animation definition: animation is making a character perform an independent action.
Stance Definition
Stance definition: stance is an action effect that a character can maintain indefinitely.
The stance includes two effects: [Basic stance] and [sub stance].
[Basic stance]: The basic stance is all the action performances in the state machine of the three mode: ground, flying and swimming. This includes our pre-made walking, running, jumping and other action performances. That is to say, when you enter the experience directly without making any modifications, the character's movements will be the effect of the basic stance.
[Sub stance]: It is an extended function of the animation system, which is independent of the complex animation logic outside the basic stance , such as the functional effects of holding a gun.
Animation
Asset
Asset description: We need to use loadAnimation to load the corresponding animation asset.
Sample script:
//Get the Player character
let chara = Player.localPlayer.character
//Load character animation asset
let animation = chara.loadAnimation("14700");
//Get the Player character
let chara = Player.localPlayer.character
//Load character animation asset
let animation = chara.loadAnimation("14700");
Animation loop times
Function description: When a character plays an animation, it plays the animation asset repeatedly until the upper limit of the number of loops is reached, and then stops playing the animation.
Practical application: You can let the NPC play actions in an infinite loop, or you can let the NPC wait after playing the actions.
First we place the character object in the scene
Then mount the following script
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected async onStart(): Promise<void> {
// Get the Player
let chara = Player.localPlayer.character
// Get three NPC object by GameObject ID . Replace the GameObject ID you just copy here.
let npc1 = await GameObject.asyncFindGameObjectById("02186A6A") as Character
let npc2 = await GameObject.asyncFindGameObjectById("3F58547B") as Character
let npc3 = await GameObject.asyncFindGameObjectById("0DC8EEF6") as Character
//Load character animation asset
let danceAnimation = chara.loadAnimation("14700");
//Load NPC1's animation asset
let AA = npc1.loadAnimation("14700");
// Set NPC1's animation loop times to infinite loop
AA.loop = 0;
//Load NPC2 animation asset
let BB = npc2.loadAnimation("14700");
// Set NPC1's animation loop count to 1
BB.loop = 1;
// //Since NPC3 is a four-legged appearance, the animation mode needs to be changed to customize mode.
// npc3.animationMode = AnimationMode.Custom;
//Load NPC3 animation asset
let CC = npc3.loadAnimation("181289");
// Set NPC3's animation loop count to 3 times
CC.loop = 3;
// press the "1" key to trigger the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Let the character animation play
danceAnimation.play();
//Let NPC1 animation play
AA.play();
//Let NPC2 animation play
BB.play();
//Let NPC3 animation play
CC.play();
});
}
}
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected async onStart(): Promise<void> {
// Get the Player
let chara = Player.localPlayer.character
// Get three NPC object by GameObject ID . Replace the GameObject ID you just copy here.
let npc1 = await GameObject.asyncFindGameObjectById("02186A6A") as Character
let npc2 = await GameObject.asyncFindGameObjectById("3F58547B") as Character
let npc3 = await GameObject.asyncFindGameObjectById("0DC8EEF6") as Character
//Load character animation asset
let danceAnimation = chara.loadAnimation("14700");
//Load NPC1's animation asset
let AA = npc1.loadAnimation("14700");
// Set NPC1's animation loop times to infinite loop
AA.loop = 0;
//Load NPC2 animation asset
let BB = npc2.loadAnimation("14700");
// Set NPC1's animation loop count to 1
BB.loop = 1;
// //Since NPC3 is a four-legged appearance, the animation mode needs to be changed to customize mode.
// npc3.animationMode = AnimationMode.Custom;
//Load NPC3 animation asset
let CC = npc3.loadAnimation("181289");
// Set NPC3's animation loop count to 3 times
CC.loop = 3;
// press the "1" key to trigger the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Let the character animation play
danceAnimation.play();
//Let NPC1 animation play
AA.play();
//Let NPC2 animation play
BB.play();
//Let NPC3 animation play
CC.play();
});
}
}
Finally, copy the ID of the character object we placed in the scene , and replace the ID of the character object in the script to achieve the effect.
Animation duration
Function description: The total duration of the character's animation playback.
Practical application: Currently we can only get the animation duration, the main purpose is to control the speed effect through the animation duration. For example, if the role of magician profession in the game, they will chant for x seconds to release the skill, then we need to judge whether the length of the animation meets the chanting time, if not, we need to adjust the animation playback speed to match the effect of the chanting action.
Sample script:
//Get the Player character
let chara = Player.localPlayer.character
//Load a character animation
let danceAnimation = chara.loadAnimation("14700");
//Print the total duration of the animation
console.log(danceAnimation.length);
//Get the Player character
let chara = Player.localPlayer.character
//Load a character animation
let danceAnimation = chara.loadAnimation("14700");
//Print the total duration of the animation
console.log(danceAnimation.length);
Animation Play Slot
Function description: Which parts of the character play the animation. Currently, the parts that can play animation include: whole body, upper body, and lower body.
Practical application: We can use this animation part to control the character or NPC to only play the animation of the upper body or lower body, thereby achieving the effect of animation fusion. For example, the upper body can play a greeting animation, and the lower body can play a sitting stance, achieve the different animation requirements of the upper and lower body.
Sample script:
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected async onStart(): Promise<void> {
// Get the Player
let chara = Player.localPlayer.character
//Load a character animation
let animation = chara.loadAnimation("14700");
// press the "1" key to trigger the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Set the animation playback part to the whole body
animation.slot = AnimSlot.FullyBody;
//Let the character animation play
animation.play();
});
// press the "2" key to trigger the following logic
InputUtil.onKeyDown(Keys.Two, () => {
//Set the animation playback part to the upper body
animation.slot = AnimSlot.Upper;
//Let the character animation play
animation.play();
});
// press the "3" key to trigger the following logic
InputUtil.onKeyDown(Keys.Three, () => {
//Set the animation playback part to the lower body
animation.slot = AnimSlot.Lower;
//Let the character animation play
animation.play();
});
}
}
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected async onStart(): Promise<void> {
// Get the Player
let chara = Player.localPlayer.character
//Load a character animation
let animation = chara.loadAnimation("14700");
// press the "1" key to trigger the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Set the animation playback part to the whole body
animation.slot = AnimSlot.FullyBody;
//Let the character animation play
animation.play();
});
// press the "2" key to trigger the following logic
InputUtil.onKeyDown(Keys.Two, () => {
//Set the animation playback part to the upper body
animation.slot = AnimSlot.Upper;
//Let the character animation play
animation.play();
});
// press the "3" key to trigger the following logic
InputUtil.onKeyDown(Keys.Three, () => {
//Set the animation playback part to the lower body
animation.slot = AnimSlot.Lower;
//Let the character animation play
animation.play();
});
}
}
Animation playback speed
Function description: control the playback speed of the animation. The speed here represents the playback speed multiple. When the speed is 1, it represents the initial playback speed. The larger the speed value, the faster the playback speed, and the smaller the speed value, the slower the playback speed.
Practical application: We can extend the character's animation playback time by modify the animation playback speed.
Sample script:
//Get the Player character
let chara = Player.localPlayer.character
//Load a character animation
let animation = chara.loadAnimation("14700");
// press the "1" key to trigger the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Set the animation playback speed to 0.5
animation.speed = 0.5
//Let the character animation play
animation.play();
});
//Get the Player character
let chara = Player.localPlayer.character
//Load a character animation
let animation = chara.loadAnimation("14700");
// press the "1" key to trigger the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Set the animation playback speed to 0.5
animation.speed = 0.5
//Let the character animation play
animation.play();
});
Play Function
Function description : The function of making the specified character play the animation according to the animation's loop/speed and other property .
Sample script:
// animation playback
animation.play();
// animation playback
animation.play();
Pause function
Function description : pause the character that is playing the animation and keep the animation posture when it is pause .
Sample script:
// pause the animation
animation.pause();
// pause the animation
animation.pause();
Resume Function
Function description : redo the character whose animation has been pause and continue to play the subsequent animation.
Sample script:
//Continue playing the animation
animation.resume();
//Continue playing the animation
animation.resume();
Stop function
Function description : Stop the character that is playing the animation and redo it to the default standby state.
Sample script:
//Stop playing the animation
animation.stop();
//Stop playing the animation
animation.stop();
Is Playing
Function description: detect whether the animation is still playing.
Practical application: For example, we want to prevent the character from moving while playing an action. It is necessary to determine whether the character is playing an animation to shield the character's operating system.
Sample script:
// Check if the animation is playing
if (animation.isPlaying == true) {
//If the animation is playing, execute the logic
} else {
//If the animation does not play, execute the logic
}
// Check if the animation is playing
if (animation.isPlaying == true) {
//If the animation is playing, execute the logic
} else {
//If the animation does not play, execute the logic
}
Animation end callback
Function description: After the animation is finished playing, the end event is thrown.
Practical application: After the character completes the animation, play the effect.
- Sample script:
// Add a function to the [animation Complete] delegate to play an upgrade effect
animation.onFinish.add(() => {
// Play effect on the object ( effect ID, target object)
EffectService.playOnGameObject("106699", Player.localPlayer.character,
{
// slot position for effect playback
slotType:HumanoidSlotType.Root,
//Rotation angle of effect
rotation:new Rotation(0,0,-90)
});
});
// Add a function to the [animation Complete] delegate to play an upgrade effect
animation.onFinish.add(() => {
// Play effect on the object ( effect ID, target object)
EffectService.playOnGameObject("106699", Player.localPlayer.character,
{
// slot position for effect playback
slotType:HumanoidSlotType.Root,
//Rotation angle of effect
rotation:new Rotation(0,0,-90)
});
});
Basic stance
Setting the basic stance
Function description: Change the basic stance asset
Practical application: At present, we provide several basic stance for selection according to the character's appearance setting, including Lowpoly basic female stance, Lowpoly basic male stance, realistic basic female stance, realistic basic male stance, European and American basic female stance, European and American basic male stance, etc. Then we can switch the character's basic stance to make the character with a female appearance play the male basic stance or other stance script:
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected onStart(): void {
//Get the Player character
let chara = Player.localPlayer.character
//Load a realistic male basic stance asset
let stance = chara.loadStance("119836");
// Add a key method: press the keyboard "1" to execute the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Play the basic stance of a realistic male
stance.play();
});
}
}
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected onStart(): void {
//Get the Player character
let chara = Player.localPlayer.character
//Load a realistic male basic stance asset
let stance = chara.loadStance("119836");
// Add a key method: press the keyboard "1" to execute the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Play the basic stance of a realistic male
stance.play();
});
}
}
Play Function
Function description: Based on the loaded basic stance asset, the specified character can play the stance.
Sample script:
//Play stance
stance.play();
//Play stance
stance.play();
Stop function
Function description: According to the loaded basic stance asset, make the specified character stop the stance being played.
Sample script:
//Stop stance
stance.stop();
//Stop stance
stance.stop();
Aim offset function
Function description: After turning on the aim offset function, the character head will move in the direction of the camera and will not turn the body. When aim offset, camera movement will not affect the character effect.
Sample script:
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected onStart(): void {
//Get the Player character
let chara = Player.localPlayer.character
// Load a anime female basic stance for the character
let stance = chara.loadStance("30274");
// aim offset is disabled by default
stance.aimOffsetEnabled = false;
// Add a key method: press the keyboard "1" to execute the following logic
InputUtil.onKeyDown(Keys.One, () => {
stance.play();
// Enable aim offset
stance.aimOffsetEnabled = true;
});
}
}
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected onStart(): void {
//Get the Player character
let chara = Player.localPlayer.character
// Load a anime female basic stance for the character
let stance = chara.loadStance("30274");
// aim offset is disabled by default
stance.aimOffsetEnabled = false;
// Add a key method: press the keyboard "1" to execute the following logic
InputUtil.onKeyDown(Keys.One, () => {
stance.play();
// Enable aim offset
stance.aimOffsetEnabled = true;
});
}
}
Sub stance
Setting the sub stance
Function description: Change the sub stance asset
Sample script:
//Get the Player character
let chara = Player.localPlayer.character
//Load a basic stance asset
let subStance = chara.loadSubStance("94258");
//Get the Player character
let chara = Player.localPlayer.character
//Load a basic stance asset
let subStance = chara.loadSubStance("94258");
The usage of functions such as [Play] and [Stop] is the same as the basic stance.
Stance Mixing
Function description : According to the asset of the loaded sub stance , the character only plays the upper body effect, lower body effect or full body effect of the stance.
Practical application: When playing shoot experience, the character upper body is often required to maintain a gun-holding stance, and the lower body will be integrated according to the basic stance. achieve the effect that the character can stance while holding a gun.
Sample script:
@Component
export default class stanceTest extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected onStart(): void {
// Get the Player character
let chara = Player.localPlayer.character
//Load a sub stance asset(holding a gun with both hands)
let stance = chara.loadSubStance("94258");
//Set the stance effect to full body stance
//stance.blendMode = StanceBlendMode.WholeBody;
//Set the stance effect to lower body stance
//stance.blendMode = StanceBlendMode.BlendLower;
//Set the stance effect to upper body effect
stance.blendMode = StanceBlendMode.BlendUpper;
// Add a key method: press the keyboard "1" to execute the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Play stance
stance.play();
});
}
}
@Component
export default class stanceTest extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected onStart(): void {
// Get the Player character
let chara = Player.localPlayer.character
//Load a sub stance asset(holding a gun with both hands)
let stance = chara.loadSubStance("94258");
//Set the stance effect to full body stance
//stance.blendMode = StanceBlendMode.WholeBody;
//Set the stance effect to lower body stance
//stance.blendMode = StanceBlendMode.BlendLower;
//Set the stance effect to upper body effect
stance.blendMode = StanceBlendMode.BlendUpper;
// Add a key method: press the keyboard "1" to execute the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Play stance
stance.play();
});
}
}
Animation stance
Function description: The loadSubStance() method can be filled with stance asset or animation asset. If the asset type is identified as an animation asset, the character will automatically play the stance effect of its animation . This allows us to control action asset effects more flexibly.
Practical application: We can choose the desired animation to convert into stance to achieve the effect. For example, there are animation asset of sitting cross-legged in the asset library . We can use the StanceBlendMode function to keep only the lower body effect, so that the character achieve stance cross-legged. Then combine it with other animation requirements to achieve the effect of animation fusion, such as sitting cross-legged and drinking tea.
Sample script:
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected onStart(): void {
// Get the Player
let chara = Player.localPlayer.character
//Convert the animation asset of sitting and greeting to the sub stance
let stance = chara.loadSubStance("29753");
//Load a waving character animation
let animation = chara.loadAnimation("29775");
// Add a key method: press the keyboard "1" to execute the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Set the stance effect to full body stance
stance.blendMode = StanceBlendMode.WholeBody;
//Play stance
stance.play();
});
// Add a key method: press the keyboard "2" to execute the following logic
InputUtil.onKeyDown(Keys.Two, () => {
//Stop stance
stance.stop();
//Set the stance effect to lower body stance
stance.blendMode = StanceBlendMode.BlendLower;
//Play stance
stance.play();
});
// Add a key method: press the keyboard "3" to execute the following logic
InputUtil.onKeyDown(Keys.Three, () => {
//Set the animation playback part to the upper body
animation.slot = AnimSlot.Upper;
//Play animation
animation.play();
});
}
}
@Component
export default class NewScript extends Script {
/** When the script is instantiated, this function will be call before the first frame is update */
protected onStart(): void {
// Get the Player
let chara = Player.localPlayer.character
//Convert the animation asset of sitting and greeting to the sub stance
let stance = chara.loadSubStance("29753");
//Load a waving character animation
let animation = chara.loadAnimation("29775");
// Add a key method: press the keyboard "1" to execute the following logic
InputUtil.onKeyDown(Keys.One, () => {
//Set the stance effect to full body stance
stance.blendMode = StanceBlendMode.WholeBody;
//Play stance
stance.play();
});
// Add a key method: press the keyboard "2" to execute the following logic
InputUtil.onKeyDown(Keys.Two, () => {
//Stop stance
stance.stop();
//Set the stance effect to lower body stance
stance.blendMode = StanceBlendMode.BlendLower;
//Play stance
stance.play();
});
// Add a key method: press the keyboard "3" to execute the following logic
InputUtil.onKeyDown(Keys.Three, () => {
//Set the animation playback part to the upper body
animation.slot = AnimSlot.Upper;
//Play animation
animation.play();
});
}
}