The Animation Controller Builder is a utility class in AzureLib that simplifies the creation and configuration of AzAnimationController instances. It provides a fluent API for defining animation behaviors such as speed, easing types, transitions, and custom keyframe callbacks, ensuring that animations are as smooth and configurable as possible.
Overview
The AzAnimationControllerBuilder is tightly integrated with the AzAnimator framework and is used to create AzAnimationController objects. These controllers drive animations for animatable objects (like entities, blocks, or items) by managing both the state of the animation and additional properties like speed, transitions, and actions triggered at specific keyframes.
Key Features
- Fluent API for defining animation properties.
- Supports custom easing types for smooth transitions.
- Allows integration of keyframe-based callbacks.
- Layers several controllers on the same bones with weights, additive blending and bone masks.
- Simplifies animation controller creation with clear, chainable methods.
Class Definition
The AzAnimationControllerBuilder is designed to work with any animatable type T. Where T is the type of object (e.g., entity or block) that the animation controller targets.
Builder Methods
Here’s a breakdown of the builder’s methods:
1. setAnimationSpeed(double animationSpeed)
Specifies the speed at which the animation should play:
- Default:
1.0(normal speed). - Usage Example:
builder(...).setAnimationSpeed(2.0).build(); // Play the animation at double the normal speed.
2. setKeyframeCallbacks(AzKeyframeCallbacks<T> keyframeCallbacks)
Please see Adding Effect Keyframes for this.
3. setEasingType(AzEasingType easingType)
Defines the easing function for the animation, influencing how values interpolate over time.
- Options: Supports predefined easing types (e.g., LINEAR, STEP, CATMULLROM).
- Usage Example:
builder(...).setEasingType(AzEasingType.STEP).build();
4. setTransitionLength(int transitionLength)
Configures the length of time (in ticks) that the controller should take to transition between animation states.
- Default:
0(instant transition). - Usage Example:
builder(...).setTransitionLength(10).build(); // Smooth transition over half a second (10 ticks).
5. setWeight(double weight)
Sets how strongly this controller's animation is applied, from 0 (no effect) to 1 (full). See Layering Controllers.
- Default:
1.0. - Usage Example:
builder(...).setWeight(0.5).build(); // Apply the animation at half strength.
6. setBlendMode(AzBlendMode blendMode)
Sets how this controller combines with controllers added before it on the same bones. See Layering Controllers.
- Options:
AzBlendMode.OVERRIDEorAzBlendMode.ADDITIVE. - Default:
AzBlendMode.OVERRIDE. - Usage Example:
builder(...).setBlendMode(AzBlendMode.ADDITIVE).build();
7. setBoneMask(AzBoneMask boneMask)
Limits which bones this controller animates. A named bone includes all of its child bones.
- Options:
AzBoneMask.only(...),AzBoneMask.except(...), orAzBoneMask.ALL. - Default:
AzBoneMask.ALL. - Usage Example:
builder(...).setBoneMask(AzBoneMask.only("upper_body")).build(); // The upper body and everything under it.builder(...).setBoneMask(AzBoneMask.except("left_leg", "right_leg")).build(); // Everything except the legs.
8. build()
Builds and returns the AzAnimationController instance based on the configured properties.
Layering Controllers
Several controllers can animate the same bones at once. Controllers are applied in the order they are added in registerControllers, so add your base layer first and the layers that go on top of it after.
For each bone, a controller combines its animation with whatever the controllers before it wrote to that bone, or with the model's default pose if none did:
AzBlendMode.OVERRIDEblends toward this controller's animation by its weight. At weight1it fully replaces what is underneath; at0.5it lands halfway.AzBlendMode.ADDITIVEadds this controller's movement on top of what is underneath, such as breathing or recoil over a walk cycle. The weight scales how much is added.
A controller at weight 0 has no effect, and bones that no controller animates ease back to their default pose as usual.
Example
A walk cycle on the whole body, an aiming pose that takes over the upper body, and breathing added on top:
@Overridepublic void registerControllers(AzAnimationControllerContainer<YourEntity> animationControllerContainer) {animationControllerContainer.add(AzAnimationController.builder(this, "base").build(),AzAnimationController.builder(this, "aim").setBoneMask(AzBoneMask.only("upper_body")).setWeight(0) // Faded in when the entity starts aiming..build(),AzAnimationController.builder(this, "breathe").setBlendMode(AzBlendMode.ADDITIVE).setWeight(0.6).build());}
Changing Weights at Runtime
Weights can be changed while the game is running, either instantly or as a fade over a number of ticks so a layer eases in or out instead of popping:
var aim = this.getAnimationControllerContainer().getOrNull("aim");aim.setWeight(1); // Instantly.aim.fadeWeight(1, 5); // Over 5 ticks.aim.fadeWeight(0, 10); // Fade back out over 10 ticks.
These methods change the weight only on the side that calls them. To set a weight from the server, send it as a command with setWeight or fadeWeight; see the AzCommands 101 page.
Fades run smoothly between game ticks, pause while the game is paused, and are not affected by animation speed. Starting a new fade, or calling setWeight, replaces the current one.