Skip to content

Defining Animations in Code (Geckolib3)

Tslat edited this page Jul 3, 2023 · 4 revisions

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.

Animation Fundamentals

IAnimatable

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:

  1. getFactory
  2. registerControllers

AnimationFactory

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

AnimationController

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.

Controller State

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.

Animation Manipulation

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.

AnimationEvent

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

Animation/Bone Transitions

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.

Easings

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.

Custom Easing

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.

Table of Contents

Geckolib 3
Geckolib 4

Hosted By: Cloudsmith

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.

Clone this wiki locally