前面我们创建了一个实体,但是其实Entity有很多子类,运用这些子类会更便捷与我们的开发

一.先创建我们的实体三件套

主体

public class FirstAnimal extends Animal {
    //构造方法
    public FirstAnimal(EntityType<? extends Animal> entityType, Level level) {
        super(entityType, level);
    }
    //注册Goal
    @Override
    protected void registerGoals() {
        this.goalSelector.addGoal(0,new MyGoal(this));
    }
    //属性
    public static AttributeSupplier.Builder createAttributes() {
        return Mob.createMobAttributes()
                .add(Attributes.MAX_HEALTH, 20.0);
    }
    //繁殖
    @Override
    public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob otherParent) {
        return null;
    }
}

模型

public class AnimalModel extends EntityModel<FirstAnimal> {
    public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(new ResourceLocation(TestMod.MODID, "first_animal"), "main");
    private final ModelPart body;
    //构造方法
    public AnimalModel(ModelPart modelPart) {
        this.body = modelPart.getChild("body");
    }
    // 创建模型层
    public static LayerDefinition createBodyLayer() {
        MeshDefinition meshdefinition = new MeshDefinition();
        PartDefinition partdefinition = meshdefinition.getRoot();

        PartDefinition body =
                partdefinition.addOrReplaceChild("body",
                        CubeListBuilder.create().
                                texOffs(0, 0).
                                addBox(-8.0F,
                                        -20.0F,
                                        -8.0F,
                                        16.0F,
                                        11.0F,
                                        16.0F,
                                        new CubeDeformation(0.0F)),
                        PartPose.offset(0.0F, 24.0F, 0.0F));

        return LayerDefinition.create(meshdefinition, 64, 64);
    }
    //动画
    @Override
    public void setupAnim(FirstAnimal firstAnimal, float v, float v1, float v2, float v3, float v4) {

    }
    // 渲染模型
    @Override
    public void renderToBuffer(PoseStack poseStack, VertexConsumer vertexConsumer, int i, int i1, float v, float v1, float v2, float v3) {
        body.render(poseStack, vertexConsumer, i, i1, v, v1, v2, v3);
    }
}

渲染

public class AnimalRenderer extends MobRenderer<FirstAnimal, AnimalModel> {
    // 构造函数
    public AnimalRenderer(EntityRendererProvider.Context context) {
        super(context, new AnimalModel(context.bakeLayer(AnimalModel.LAYER_LOCATION)), 1f);
    }
    // 返回实体的纹理
    @Override
    public ResourceLocation getTextureLocation(FirstAnimal firstAnimal) {
        return new ResourceLocation(TestMod.MODID, "textures/entity/first_animal.png");
    }
}

二.创建Goal

在FirstAnimal里我们有一个用于注册Goal的方法
Goal其实就是实体的AI行为

public class MyGoal extends Goal {
    private FirstAnimal animal;
    // 构造方法
    public MyGoal(FirstAnimal animal) {
        this.animal = animal;
    }
    //执行逻辑,给附近玩家饥饿效果
    @Override
    public boolean canUse() {
        Level level = this.animal.level();
        if(!level.isClientSide){
            Player nearestPlayer = level.getNearestPlayer(this.animal, 10);
            if(nearestPlayer!=null){
                nearestPlayer.addEffect(new MobEffectInstance(MobEffects.HUNGER, 3 * 20, 3));
            }

        }
        return true;
    }
}

三.最后把他们注册进去

这部分同实体

public static final Supplier<EntityType<FirstAnimal>> FIRST_ANIMAL =
            ENTITY_TYPES.register("first_animal",
                    () -> EntityType.Builder.of(FirstAnimal::new, MobCategory.MISC).build("first_animal"));
@SubscribeEvent
public static void registerEntityLayers(EntityRenderersEvent.RegisterLayerDefinitions evt) {
    evt.registerLayerDefinition(AnimalModel.LAYER_LOCATION, AnimalModel::createBodyLayer);
}
@SubscribeEvent
public static void onClientEvent(FMLClientSetupEvent event){
    event.enqueueWork(()->{
        EntityRenderers.register(Registry.FIRST_ANIMAL.get(), AnimalRenderer ::new);
    });
}

这里需要额外注册我们Animal的属性

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
    public static class ModEventBus{
        @SubscribeEvent
        public static void setupAttributes(EntityAttributeCreationEvent event) {
            event.put(Registry.FIRST_ANIMAL.get(), FirstAnimal.createAttributes().build());
        }
    }

ClientEventHandler 完整代码(包含了Entity的部分)

@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD,value = Dist.CLIENT)
public class ClientEventHandler {
    @SubscribeEvent
    public static void registerEntityLayers(EntityRenderersEvent.RegisterLayerDefinitions evt) {
        evt.registerLayerDefinition(FlyingSwordModel.LAYER_LOCATION, FlyingSwordModel::createBodyLayer);
        evt.registerLayerDefinition(AnimalModel.LAYER_LOCATION, AnimalModel::createBodyLayer);
    }
    @SubscribeEvent
    public static void onClientEvent(FMLClientSetupEvent event){
        event.enqueueWork(()->{
            EntityRenderers.register(Registry.FLYING_SWORD_ENTITY.get(), FlyingSwordEntityRenderer::new);
        });
        event.enqueueWork(()->{
            EntityRenderers.register(Registry.FIRST_ANIMAL.get(), AnimalRenderer ::new);
        });
    }
    @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
    public static class ModEventBus{
        @SubscribeEvent
        public static void setupAttributes(EntityAttributeCreationEvent event) {
            event.put(Registry.FIRST_ANIMAL.get(), FirstAnimal.createAttributes().build());
        }

    }
}