-
Notifications
You must be signed in to change notification settings - Fork 6
Using DisplayAnimatorStateMachines (v2.5.7 and lower)
Jay edited this page Jan 14, 2025
·
1 revision
DisplayAnimatorStateMachines can be used to switch between different animations for a SpawnedDisplayEntityGroup/model based on given conditions. When a state's conditions are met, the state machine will automatically switch from one animation to another. This guide represents what steps were taken to create the Dodo Bird's State Machine found in the README
Before creating a state machine you need something to control the states (in this case an entity) and a SpawnedDisplayEntityGroup
Location spawnLocation = yourMethodToGetASpawnLocation()
//Spawn a chicken that will act as the dodo bird and control the animation states
Chicken chicken = spawnLocation.getWorld().spawn(spawnLocation, Chicken.class, c -> {
c.setInvisible(true);
c.setSilent(true);
c.getAttribute(Attribute.GENERIC_SCALE).setBaseValue(1.2f);
c.getAttribute(Attribute.GENERIC_GRAVITY).setBaseValue(0.16f);
c.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.2f);
c.getAttribute(Attribute.GENERIC_JUMP_STRENGTH).setBaseValue(0.6f);
});
//Spawn the dodo bird model
DisplayEntityGroup dodoBirdModel = yourMethodToGetADisplayEntityGroup();
SpawnedDisplayEntityGroup dodoBird = dodoBirdModel.spawn(chicken.getLocation(), GroupSpawnedEvent.SpawnReason.CUSTOM);
dodoBird.setPitch(0); //Sets the pitch of all parts within the group to 0
//Attach the model to the spawned chicken entity, follow it's body yaw.
//Despawn the model 20 ticks after the chicken dies, no interaction pivots, with a teleport duration of 2 ticks
dodoBird.rideEntity(chicken);
dodoBird.followEntityDirection(chicken, FollowType.BODY, 20, false, 2);//Create a State Machine for the dodo bird model
DisplayAnimatorStateMachine stateMachine = new DisplayAnimatorStateMachine();
//Get SpawnedDisplayAnimations for state machine
SpawnedDisplayAnimation idleAnimation = yourMethodToGetASpawnedDisplayAnimation();
SpawnedDisplayAnimation walkingAnimation = yourMethodToGetASpawnedDisplayAnimation();
SpawnedDisplayAnimation flappingAnimation = yourMethodToGetASpawnedDisplayAnimation();
SpawnedDisplayAnimation deathAnimation = yourMethodToGetASpawnedDisplayAnimation();
//Create animation states for the dodo bird with a given name, animation, and whether it should loop when the state is changed.
stateMachine.addState("idle", idleAnimation, true);
stateMachine.addState("walking", walkingAnimation, true);
stateMachine.addState("flapping", flappingAnimation, true);
stateMachine.addState("dead", deathAnimation, false);Internally the state transition task uses a BukkitRunnable, so you do not need to create one when controlling state conditions
//Set the condition for each state in the state machine
//These conditions will apply to every SpawnedDisplayEntityGroup that is using this state machine
stateMachine.setStateTransitionTask(model -> { //"model" represents a SpawnedDisplayEntityGroup within this lambda
Entity vehicle = model.getVehicle();
if (!(vehicle instanceof Chicken c)) {
return;
}
if (c.isDead()){
stateMachine.setState("dead", model);
return;
}
Vector chickenVelocity = c.getVelocity();
//In Water
if (c.isInWater()) {
stateMachine.setState("flapping", model); //Set state to flapping if in water
}
//Block below chicken is air (is falling/jumping)
else if (c.getLocation().subtract(0, 0.2, 0).getBlock().getType() == Material.AIR) {
stateMachine.setState("flapping", model); //Set state to flapping if in air
}
else {
//Moving
if (Math.abs(chickenVelocity.getX()) > 0.001 || Math.abs(chickenVelocity.getZ()) > 0.001) {
stateMachine.setState("walking", model); //Set state to walking if moving
}
//Not moving
else {
stateMachine.setState("idle", model); //Set state to idle if not moving
}
}
}, 1); //Determines how often these checks will be made, in ticks.//Add a group. The group MUST be added after state conditions have been set
stateMachine.addGroup(dodoBird);
//Remove a group (Groups are automatically removed from a state machine when they are unregistered)
stateMachine.removeGroup(dodoBird);
//Unregister the state machine, removing all groups and animation states
stateMachine.unregister();