-
Notifications
You must be signed in to change notification settings - Fork 0
The Animation Controller
The AnimationController is the core class for managing animations in PulseLib animatables.
It provides an entry point to control animations through the AnimationStateHandler
- Each
AnimationControllerhandles ONE animation at a time - Animatables can have multiple controllers, allowing multiple animations to run simultaneously
When creating an animatable, you’ll implement the registerControllers method. This is where you add as many controllers as you need:
public void registerAnimationControllers(PAnimationManager.PAnimationRegistrar<?> registrar)
{
}Note
If your animatable does not have any animations, you do not need to register any controllers.
Controllers are added to the registrar and configured as needed.
Example: Basic conditional controller
@Override
public void registerAnimationControllers(PAnimationManager.PAnimationRegistrar<TestBlockEntity> registrar)
{
registrar.add(new PAnimationController<>(animatableState ->
{
TestBlockEntity blockEntity = animatableState.animatable();
PAnimationController<TestBlockEntity> controller = animatableState.controller();
if (blockEntity.isPlayAnimation())
{
controller.play(ANIMATION);
return ControllerState.PLAY;
}
else
{
controller.stop();
return ControllerState.STOP;
}
}));
}- The order of registration matters.
- Controllers are executed in registration order; later controllers can override earlier ones.
Register broad animations first (e.g., walking, idling), then more specific animations (e.g., attack, interact) afterwards. Example: A walk/idle controller first, followed by an attack controller, allows the entity to swing its arm while walking — blending animations naturally.
When creating an PAnimationController, you can pass several parameters:
-
name– A unique name for the controller, typically related to its purpose (e.g., "Walking"). -
animationHandler– A predicate (StateHandler) that decides which animation(s) should play and when. See the StateHandler for details.
The AnimationStateHandler determines what animation a controller plays and when.
- It receives an instance of AnimatableState
- Returns a ControllerState
Note
StateHandler is called every render frame, allowing real-time animation updates. Treat it as the controller’s current “state,” not as a start/stop trigger.
Example 1 - Basic idling
public void registerAnimationControllers(PAnimationManager.PAnimationRegistrar<?> registrar)
{
registrar.add(new PAnimationController<>("idling", animatableState ->
{
if (animatableState.animatable().isIdling())
{
controller.play(IDLE);
return ControllerState.PLAY;
}
else
{
controller.stop();
return ControllerState.STOP;
}
}));
}This controller plays an idling animation when the animatable is idle, or stops the animation otherwise.
Example 2 - Walking + Running + Idling
public void registerAnimationControllers(PAnimationManager.PAnimationRegistrar<TestEntity> registrar)
{
registrar.add(new PAnimationController<>("walk/idle/run", state ->
{
if (state.animatable().isMoving())
{
state.controller().play(TestEntity.this.isSprinting() ? RUN : WALK);
return ControllerState.PLAY;
}
else
{
state.controller().play(IDLE);
return ControllerState.PLAY;
}
}));
}This example chooses between walking, running, or idling depending on movement and sprinting status.
Notice we never return STOP; the controller is always playing an animation.
Example 3 - Spawning
public void registerAnimationControllers(PAnimationManager.PAnimationRegistrar<TestEntity> registrar)
{
registrar.add(new PAnimationController<>("spawn", state ->
{
if (MyEntity.this.tickCount < 100)
{
state.controller().play(SPAWN_ANIMATION);
return ControllerState.PLAY;
}
return ControllerState.STOP;
}));
}Plays a spawn animation for the first 100 ticks (5 seconds) after the entity enters the world. After 100 ticks, the controller stops.
Example 4 - Attack animation
public void registerAnimationControllers(PAnimationManager.PAnimationRegistrar<TestEntity> registrar)
{
registrar.add(new PAnimationController<>("attack", state ->
{
if (state.animatable().swinging)
{
state.controller().play(ATTACK);
return ControllerState.PLAY;
}
return ControllerState.STOP;
}));
}Plays an attack animation when the entity is swinging its arm. If the entity stops swinging, the controller resets and stops the animation.
Start
Basics
In depth
Specifics