Skip to content

Commit

Permalink
Removed unused method from IAnimationTickable
Browse files Browse the repository at this point in the history
Wrote documentation for the example entity
  • Loading branch information
Goodbird committed Mar 19, 2024
1 parent 62292bf commit db6f460
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 117 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package software.bernie.geckolib3.core;

public interface IAnimationTickable {
public void tick();

public int tickTimer();
}
Original file line number Diff line number Diff line change
@@ -1,38 +1,44 @@
package software.bernie.example.client.model.entity;
package software.bernie.example.client.model.entity; //The package our class is located in

//Imports of the classes used in this class description
import net.minecraft.util.ResourceLocation;
import software.bernie.example.GeckoLibMod;
import software.bernie.example.entity.GeoExampleEntity;
import software.bernie.geckolib3.GeckoLib;
import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
import software.bernie.geckolib3.core.processor.IBone;
import software.bernie.geckolib3.model.AnimatedTickingGeoModel;
import software.bernie.geckolib3.model.provider.data.EntityModelData;
import software.bernie.geckolib3.particles.emitter.BedrockEmitter;

//The model class is derived from the AnimatedTickingGeoModel with the template argument(<>) set to the previously made entity class
public class ExampleEntityModel extends AnimatedTickingGeoModel<GeoExampleEntity> {

//This method should return a ResourceLocation for the animation file based on the entity state
@Override
public ResourceLocation getAnimationFileLocation(GeoExampleEntity entity) {
return new ResourceLocation(GeckoLib.ModID, "animations/bat.animation.json");
}

//This method should return a ResourceLocation for the model file based on the entity state
@Override
public ResourceLocation getModelLocation(GeoExampleEntity entity) {
return new ResourceLocation(GeckoLib.ModID, "geo/bat.geo.json");
}

//This method should return a ResourceLocation for the texture file based on the entity state
@Override
public ResourceLocation getTextureLocation(GeoExampleEntity entity) {
return new ResourceLocation(GeckoLib.ModID, "textures/model/entity/bat.png");
}

//This function allows you to change model properties each frame before render
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void setLivingAnimations(GeoExampleEntity entity, Integer uniqueID, AnimationEvent customPredicate) {
super.setLivingAnimations(entity, uniqueID, customPredicate);
IBone head = this.getAnimationProcessor().getBone("head");
EntityModelData extraData = (EntityModelData) customPredicate.getExtraDataOfType(EntityModelData.class).get(0);
public void setLivingAnimations(GeoExampleEntity entity, Integer uniqueID, AnimationEvent animationEvent) {
super.setLivingAnimations(entity, uniqueID, animationEvent); //We call the super-function
IBone head = this.getAnimationProcessor().getBone("head"); //Then we take the head bone
//We get the model data for an entity
EntityModelData extraData = (EntityModelData) animationEvent.getExtraDataOfType(EntityModelData.class).get(0);
//And we set the head bone rotation to the interpolated pitch and yaw rotations of an entity
head.setRotationX(extraData.headPitch * ((float) Math.PI / 180F));
head.setRotationY(extraData.netHeadYaw * ((float) Math.PI / 180F));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,25 @@
package software.bernie.example.client.renderer.entity;
package software.bernie.example.client.renderer.entity; //The package our class is located in

import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderEntity;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.Entity;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
//Imports of the classes used in this class description
import software.bernie.example.client.model.entity.ExampleEntityModel;
import software.bernie.example.entity.GeoExampleEntity;
import software.bernie.geckolib3.geo.render.built.GeoModel;
import software.bernie.geckolib3.particles.emitter.BedrockEmitter;
import software.bernie.geckolib3.core.util.Color;
import software.bernie.geckolib3.renderers.geo.GeoEntityRenderer;
import software.bernie.geckolib3.util.MatrixStack;

import javax.vecmath.Matrix3f;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

//The model class is derived from the GeoEntityRenderer with the template argument(<>) set to the previously made entity class
public class ExampleGeoRenderer extends GeoEntityRenderer<GeoExampleEntity> {

//The constructor defines the model which will be used
public ExampleGeoRenderer() {
super(new ExampleEntityModel());
super(new ExampleEntityModel()); // Here we pass the previously made model into the super-constructor
}

@Override
public void renderAfter(GeoModel model, GeoExampleEntity animatable, float ticks, float red, float green, float blue, float alpha) {
BedrockEmitter emitter = animatable.emitter;
emitter.prevGlobal.x=emitter.lastGlobal.x;
emitter.prevGlobal.y=emitter.lastGlobal.y;
emitter.prevGlobal.z=emitter.lastGlobal.z;

emitter.lastGlobal.x=animatable.posX;
emitter.lastGlobal.y=animatable.posY;
emitter.lastGlobal.z=animatable.posZ;
RenderHelper.disableStandardItemLighting();

boolean shouldSit = (animatable.ridingEntity != null && animatable.ridingEntity.shouldRiderSit());
Pair<Float,Float> rotations = calculateRotations(animatable,ticks,shouldSit);
deapplyRotations(animatable,this.handleRotationFloat(animatable, ticks),rotations.getKey(),ticks);

GL11.glTranslated(-animatable.posX,-animatable.posY,-animatable.posZ);
emitter.rotation.setIdentity();

MATRIX_STACK.push();
//MATRIX_STACK.rotateY((float) (Math.PI/2));
// MATRIX_STACK.translate(1,1,0);
// MATRIX_STACK.rotateY((float) (Math.PI/2));
// MATRIX_STACK.scale(5,5,5);

Matrix4f full = MATRIX_STACK.getModelMatrix();
emitter.rotation = new Matrix3f(full.m00,full.m01,full.m02,full.m10,full.m11,full.m12,full.m20,full.m21,full.m22);
emitter.lastGlobal.x+=full.m03;
emitter.lastGlobal.y+=full.m13;
emitter.lastGlobal.z+=full.m23;

MATRIX_STACK.pop();
emitter.render(ticks);
RenderHelper.enableStandardItemLighting();
}
//This function specifiec the color/tint of the model rendered
//By default the model does not color red when hurt. If you want change that, you can do it like that
public Color getRenderColor(GeoExampleEntity animatable, float partialTicks) {
if(animatable.hurtTime>0 || animatable.deathTime > 0) { //If the hurt or death timers are greater then zero, then
return Color.ofRGBA(255, 153, 153, 255); //We say that the model should be colored red (you can set here any RGBA color)
}
return Color.ofRGBA(255,255,255,255); //Else we return the regular white color (and again, here can be any color you want)
}
}
69 changes: 25 additions & 44 deletions src/main/java/software/bernie/example/entity/GeoExampleEntity.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package software.bernie.example.entity;
package software.bernie.example.entity; //The package our class is located in

import net.minecraft.client.Minecraft;
//Imports of the classes used in this class description
import net.minecraft.entity.EntityCreature;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import software.bernie.example.GeckoLibMod;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.IAnimationTickable;
import software.bernie.geckolib3.core.PlayState;
Expand All @@ -14,66 +13,48 @@
import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
import software.bernie.geckolib3.core.manager.AnimationData;
import software.bernie.geckolib3.core.manager.AnimationFactory;
import software.bernie.geckolib3.particles.BedrockLibrary;
import software.bernie.geckolib3.particles.emitter.BedrockEmitter;

//Our entity will be derived from the EntityCreature class, meaning that it will be a peaceful creature with some simple AI
//It will also implement IAnimatable and IAnimationTickable interfaces, which are required for something to have a geckolib animated model
public class GeoExampleEntity extends EntityCreature implements IAnimatable, IAnimationTickable {
private AnimationFactory factory = new AnimationFactory(this);
public BedrockEmitter emitter;
public String particleName = "snow";
public boolean restart = false;
private <E extends IAnimatable> PlayState predicate(AnimationEvent<E> event) {
event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.bat.fly", true));
return PlayState.CONTINUE;
}
//We create a field for an animation factory - a special storage for all of the animation states for our entity
private final AnimationFactory factory = new AnimationFactory(this);

//The constructor of our class, requires a World instance and uses it for the call of super-constructor
public GeoExampleEntity(World worldIn) {
super(worldIn);
this.ignoreFrustumCheck = true;
this.ignoreFrustumCheck = true; //The entity will be rendered even if it's hitbox is not visible
//Here we add an AI task for our entity to watch the closest player in the range of 8 blocks
this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.setSize(5F, 5F);
emitter = new BedrockEmitter();
emitter.setScheme(GeckoLibMod.particleLibraryInstance.presets.get(particleName));
emitter.setTarget(Minecraft.getMinecraft().thePlayer);
emitter.start();
this.setSize(5F, 5F); //the size of the entity hitbox
}

//This function is called a predicate. It is used to determine what animation should be played and whether it should play at all
// based on the entity state, which is provided in the event argument
private <E extends IAnimatable> PlayState predicate(AnimationEvent<E> event) {
//We set the controller to play the looping "animation.bat.fly" animation
event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.bat.fly", true));
return PlayState.CONTINUE; //And we say that the animation should be played
}

//This function is used to register the animation controllers, which will play animations determined by the predicate given
@Override
public void registerControllers(AnimationData data) {
data.addAnimationController(new AnimationController<GeoExampleEntity>(this, "controller", 50, this::predicate));
//Here we register a controller with name "controller", with predicate referenced as this::predicate
//And we set transition length to 50 ticks, meaning that when one animation ends, the model will transition
//To the beginning of the next animation smoothly during those 50 ticks. It can be set to 0 for immediate switch between animations
data.addAnimationController(new AnimationController<>(this, "controller", 50, this::predicate));
}

//Here we add a getter-function so that geckolib could get the reference to the animation factory
@Override
public AnimationFactory getFactory() {
return this.factory;
}

//This function should return the value of a timer which will increase every tick - the ticksExisted field fits very well for that
@Override
public int tickTimer() {
return ticksExisted;
}

@Override
public void onLivingUpdate() {
//super.onLivingUpdate();
if(worldObj.isRemote) {
//setRotation(0,0);
if (!restart && emitter.scheme!=null && !emitter.scheme.toReload) {
emitter.update();
} else {
emitter.stop();
emitter = new BedrockEmitter();
emitter.setScheme(BedrockLibrary.instance.presets.get(particleName));
emitter.setTarget(this);
emitter.start();
restart = false;
}
}
}

@Override
public void tick() {
super.onUpdate();

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,4 @@ public int tickTimer() {
return ticksExisted;
}

@Override
public void tick() {
super.onUpdate();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ public int tickTimer() {
return ticksExisted;
}

@Override
public void tick() {
super.onUpdate();
}

@Override
public void onLivingUpdate() {

Expand Down

0 comments on commit db6f460

Please sign in to comment.