前面我们创建了一个实体,但是其实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());
}
}
}