-
-
Notifications
You must be signed in to change notification settings - Fork 131
Defining Animations in Code (Geckolib3)
While the basic concept of animating models is fairly straightforward in GeckoLib, the nuances can build up or provide edge cases that may catch you off-guard. This page is written to help cover the extra details and information that might be helpful in determining the correct or best way to implement your controllers and animations in the context of GeckoLib.
All animatable objects in GeckoLib3 must implement the IAnimatable
interface in one way or another. This is the base interface that represents all animatables.
This interface then requires that you override two methods:
getFactory
registerControllers
AnimationFactories are collection objects that hold and provide the animatable instances of the animatable object you're creating. This is done to differentiate instances so that they don't all animate the same as the same time. The way it does so varies between animatable types - for example an animatable item's factory will contain an instance for every unique ItemStack, whereas an entity's factory will only contain the single instance of the entity itself.
Because of this, is is IMPORTANT that you instantiate your factories with GeckolibUtil.createFactory
, and not by using the factory constructors. This allows Geckolib to choose the right factory type for your object
AnimationControllers are a multi-faceted object that is designed for a singular purpose: to handle a single concurrent animation. Because of this, it is important to note that a controller can only handle one animation at a time. Attempting to have it run another animation will cause it to drop the previous one.
In order to run multiple animations on an animatable, you need to register multiple controllers - one for each concurrent animation. Note that animations operate on the same model, so you cannot have two animations operating on the same bone, otherwise they may conflict and cause unexpected visual errors.
An animation controller has three possible states. You can find out what state a controller is in by calling AnimationController.getAnimationState
State | Explanation |
---|---|
Running | Indicates that the controller is actively playing an animation |
Transitioning | Controller is transitioning from stopped to running or from one animation to another |
Stopped | Controller is not actively running an animation. Either completely still or lerping back to the model's original state. |
To tell a controller to start/run a new animation, you call AnimationController.setAnimation
. This call caches the last provided builder, so you can safely call this method every time even if the animation is already playing without a performance penalty or conflict.
Because of this caching, animations that do not loop will only be playable once, even if calling setAnimation
again. If you want to play a non-looped animation again, you'll need to call AnimationController.markNeedsReload
. This forces the controller to load the next call as a new animation, even if it matches the one that's already cached.
You do not need to do this if you had already run another animation since the last time you played the non-looping animation.
When instantiating your controller, you will need to implement a function that handles an AnimationEvent
. This function is called every render pass, and is where you set your controller's animations.
This event instance is created anew every render frame, and is directly connected to the controller.
The PlayState
value you return from this function determines the animation state for the controller for the current render frame.
Returning PlayState.CONTINUE
will tell the controller to start or continue the set animation, whereas returning PlayState.STOP
will tell it to stop immediately
By default, GeckoLib attempts to transition linearly between one bone position and another, either when moving from one animation frame to the next, or one animation to the next.
This transition is determined by the transitionLengthTicks
value in AnimationController
, and is the int value you set when you instantiate the controller. The field is accessible, so if you want to change the transition length dynamically you can do so via that field.
Setting the value to 0 disables the transition, and instead snaps to the next position as soon as possible.
When the controller attempts to transition between one bone position and another, the default transition is linear. This transition can be configured however to be other types of transitions, such as stepped
or elastic
to give it a more interesting aesthetic.
By default this is handled in the animation json itself, but you can force the controller to use an easing of your choice via setting the AnimationController.easingType
field to one of the available options in the EasingType
enum class.
Setting the value to None
will revert back to using the animation json easing definitions.
GeckoLib allows you to provide your own easing function and use the presets.
Your function should be of type Function<Double, Double>
, where the input is a number between 0 to 1, indicating how far in a keyframe you are, and the output is the "eased" number. To read more about how this works and for a better explanation, look at easings.net.
Once you've created your function, simply assign it to AnimationController.customEasingMethod
and set AnimationController.easingType
to EasingType.CUSTOM
.
Geckolib 3
Geckolib 4
- Installation
- Getting Started
- Upgrading from GeckoLib 3.1.x to 4.0
- Updating to GeckoLib 4.5
- Basic
- Advanced
- Miscellaneous
Package repository hosting is graciously provided by Cloudsmith.
Cloudsmith is the only fully hosted, cloud-native, universal package management solution that enables your organization to create, store and share packages in any format, to any place, with total confidence.