注:1.16.5的实体教程和本文基本类似,只是一些类中的函数名称有所不同。

我们今天在1.18.1的模组中添加一个生物实体

1.新建entity文件夹 -> 文件夹中新建一个model文件夹,一个render文件夹,一个我们的生物类(以EntityRe8Dimi.java为例)

我们本次要制作一个boss类怪物,类似于凋零,具有boss血条

EntityRe8Dimi.java

package com.joy187.re8joymod.entity;import java.util.Random;
import java.util.function.Predicate;import javax.annotation.Nullable;import com.joy187.re8joymod.init.EntityInit;
import com.mojang.blaze3d.vertex.PoseStack.Pose;import net.minecraft.client.renderer.EffectInstance;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerBossEvent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.BossEvent;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MobType;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal;
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
import net.minecraft.world.entity.animal.IronGolem;
import net.minecraft.world.entity.boss.wither.WitherBoss;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.entity.monster.Ravager;
import net.minecraft.world.entity.monster.ZombifiedPiglin;
import net.minecraft.world.entity.npc.AbstractVillager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.pathfinder.BlockPathTypes;
import net.minecraftforge.client.event.RenderGameOverlayEvent.BossInfo;//我们的boss继承自劫掠兽
public class EntityRe8Dimi extends Ravager {//boss血条信息private final ServerBossEvent bossInfo = (ServerBossEvent)(new ServerBossEvent(this.getDisplayName(), BossEvent.BossBarColor.PURPLE, BossEvent.BossBarOverlay.PROGRESS)).setDarkenScreen(true);private static final EntityDataAccessor<Integer> DATA_ID_INV = SynchedEntityData.defineId(EntityRe8Dimi.class, EntityDataSerializers.INT);//我们的boss不攻击类型为不死亡灵类的生物(凋零骷髅一类)private static final Predicate<LivingEntity> LIVING_ENTITY_SELECTOR = (p_31504_) -> {return p_31504_.getMobType() != MobType.UNDEAD && p_31504_.attackable();};public EntityRe8Dimi(EntityType<? extends Ravager> type, Level worldIn) {super(type, worldIn);this.xpReward = 150;this.isNonBoss();this.isSunSensitive();this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F);}//是否怕阳光protected boolean isSunSensitive() {return true;}public void aiStep() {super.aiStep();}//设置生物属性(最大血量、移动速度、攻击力、护甲值等)public static AttributeSupplier.Builder prepareAttributes() {return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 120.0D).add(Attributes.MOVEMENT_SPEED, 0.28D).add(Attributes.FOLLOW_RANGE, 48.0D).add(Attributes.ARMOR, 8.0D).add(Attributes.ARMOR_TOUGHNESS, 10.0D).add(Attributes.KNOCKBACK_RESISTANCE, 0.85D).add(Attributes.ATTACK_DAMAGE, 9.0D);}//给生物设置攻击行为@Overrideprotected void registerGoals() {super.registerGoals();this.goalSelector.addGoal(1, new RandomLookAroundGoal(this));this.goalSelector.addGoal(2, new LookAtPlayerGoal(this, Player.class, 8.0F));this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 0, false, false, LIVING_ENTITY_SELECTOR));this.addBehaviourGoals();}//给生物添加其行为protected void addBehaviourGoals() {this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D));this.targetSelector.addGoal(1, (new HurtByTargetGoal(this)).setAlertOthers(ZombifiedPiglin.class));this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false));this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
//        this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, EntityEthan.class, true));}//生物攻击其他生物public boolean doHurtTarget(Entity entityIn) {if(!super.doHurtTarget(entityIn)){return false;}else{//如果攻击的对象是生物,就给这个对象一个凋零效果,持续1s(20ticks=1s)if(entityIn instanceof LivingEntity){((LivingEntity)entityIn).addEffect(new MobEffectInstance(MobEffects.WITHER, 20,0,true,true));}return true;}}//生物死亡音效@Overrideprotected SoundEvent getDeathSound() {
//        Random ran = new Random();
//        int co = ran.nextInt(3);
//        if(co==0)
//        {
//            return SoundInit.ENTITY_DIMI_DEATH1.get();
//        }
//        else if(co==1) return SoundInit.ENTITY_DIMI_DEATH2.get();return SoundEvents.BEE_DEATH;}// 生物在玩家身边的音效protected SoundEvent getAmbientSound() {
//        Random ran = new Random();
//        int co = ran.nextInt(2);
//        if(co==0)
//        {
//            return SoundInit.ENTITY_DIMI_AMBIENT1.get();
//        }
//        return  SoundInit.ENTITY_DIMI_AMBIENT2.get();return SoundEvents.ZOMBIE_AMBIENT;}
//    生物受伤音效
//    @Override
//    protected SoundEvent getHurtSound(DamageSource source) {
//        Random ran = new Random();
//        int co = ran.nextInt(2);
//        if(co==0)
//        {
//            return SoundInit.ENTITY_DIMI_HURT1.get();
//        }
//        return SoundInit.ENTITY_DIMI_HURT2.get();
//    }protected float getStandingEyeHeight(Pose p_213348_1_, EntityDimensions p_213348_2_) {return 3F;}public void setInvulnerableTicks(int p_82215_1_) {this.entityData.set(DATA_ID_INV, p_82215_1_);}public void readAdditionalSaveData(CompoundTag p_70037_1_) {super.readAdditionalSaveData(p_70037_1_);this.setInvulnerableTicks(p_70037_1_.getInt("Invul"));if (this.hasCustomName()) {this.bossInfo.setName(this.getDisplayName());}}public void setCustomName(@Nullable Component p_200203_1_) {super.setCustomName(p_200203_1_);this.bossInfo.setName(this.getDisplayName());}protected void customServerAiStep() {super.customServerAiStep();if(this.isSunSensitive()){this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 20*10,1,true,true));}Random ran = new Random();if(this.getHealth() >= 20.0F && this.getHealth()<=30.0F){for(int i=0;i<5;i++)this.heal(1.0F*ran.nextFloat());}if(this.getHealth() >= 60.0F && this.getHealth()<=65.0F){for(int i=0;i<4;i++)this.heal(1.5F*ran.nextFloat());}//        if(this.getHealth() >= 0.1F && this.getHealth()<=10.0F)
//        {
//            this.convertTo(EntityDimi2,true);
//            EntityDimi2 e = new EntityDimi2(EntityInit.DIMI2.get(),this.level);
//            e.copyPosition(this);
//            this.level.addFreshEntity(e);
//            this.remove();
//
//        }this.bossInfo.setProgress(this.getHealth() / this.getMaxHealth());}public boolean isNonBoss(){return false;}//什么时候能看见boss血条public void startSeenByPlayer(ServerPlayer p_184178_1_) {super.startSeenByPlayer(p_184178_1_);this.bossInfo.addPlayer(p_184178_1_);}//什么时候看不见boss血条public void stopSeenByPlayer(ServerPlayer p_184203_1_) {super.stopSeenByPlayer(p_184203_1_);this.bossInfo.removePlayer(p_184203_1_);}}

打开我们的blockbench -> 制作boss的3D模型 -> 导出制作好的模型

把我们的模型文件放入上面新建的model文件夹中

ModelRe8Dimi.java

package com.joy187.re8joymod.entity.model;import com.joy187.re8joymod.Main;
import com.joy187.re8joymod.entity.EntityRe8Dimi;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;import net.minecraft.client.model.EntityModel;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.model.geom.PartPose;
import net.minecraft.client.model.geom.builders.CubeDeformation;
import net.minecraft.client.model.geom.builders.CubeListBuilder;
import net.minecraft.client.model.geom.builders.LayerDefinition;
import net.minecraft.client.model.geom.builders.MeshDefinition;
import net.minecraft.client.model.geom.builders.PartDefinition;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;// Made with Blockbench 4.1.3
// Exported for Minecraft version 1.17 with Mojang mappings
// Paste this class into your mod and generate all required importspublic class ModelRe8Dimi<T extends EntityRe8Dimi> extends EntityModel<T> {// This layer location should be baked with EntityRendererProvider.Context in the entity renderer and passed into this model's constructor//注意这个皮肤路径public static final ModelLayerLocation LAYER_LOCATION = new ModelLayerLocation(new ResourceLocation(Main.MOD_ID, "re8dimi"), "main");private final ModelPart Head;private final ModelPart Body;private final ModelPart RightArm;private final ModelPart LeftArm;private final ModelPart RightLeg;private final ModelPart LeftLeg;public ModelRe8Dimi(ModelPart root) {this.Head = root.getChild("Head");this.Body = root.getChild("Body");this.RightArm = root.getChild("RightArm");this.LeftArm = root.getChild("LeftArm");this.RightLeg = root.getChild("RightLeg");this.LeftLeg = root.getChild("LeftLeg");}public static LayerDefinition createBodyLayer() {MeshDefinition meshdefinition = new MeshDefinition();PartDefinition partdefinition = meshdefinition.getRoot();PartDefinition Head = partdefinition.addOrReplaceChild("Head", CubeListBuilder.create(), PartPose.offsetAndRotation(-0.4444F, -23.0556F, -3.3889F, -0.1047F, 0.0F, 0.0F));PartDefinition Head_r1 = Head.addOrReplaceChild("Head_r1", CubeListBuilder.create().texOffs(62, 33).addBox(-4.0F, -9.9993F, -6.9476F, 8.0F, 2.0F, 8.0F, new CubeDeformation(0.0F)).texOffs(51, 0).addBox(-7.0F, -7.9993F, -6.9476F, 14.0F, 2.0F, 8.0F, new CubeDeformation(0.0F)).texOffs(75, 43).addBox(-3.0F, -4.9993F, -10.9476F, 13.0F, 1.0F, 2.0F, new CubeDeformation(0.0F)).texOffs(87, 0).addBox(-12.0F, -4.9993F, -10.9476F, 9.0F, 2.0F, 2.0F, new CubeDeformation(0.0F)).texOffs(0, 77).addBox(-13.0F, -4.9993F, -10.9476F, 1.0F, 2.0F, 15.0F, new CubeDeformation(0.0F)).texOffs(68, 66).addBox(9.0F, -5.9993F, -9.9476F, 3.0F, 1.0F, 14.0F, new CubeDeformation(0.0F)).texOffs(0, 23).addBox(-12.0F, -5.9993F, -9.9476F, 21.0F, 2.0F, 14.0F, new CubeDeformation(0.0F)).texOffs(32, 80).addBox(-4.0F, -5.9993F, -6.9476F, 8.0F, 8.0F, 8.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.4444F, 3.0556F, 5.3889F, 0.1309F, 0.0F, 0.0F));PartDefinition Body = partdefinition.addOrReplaceChild("Body", CubeListBuilder.create().texOffs(56, 12).addBox(-6.0F, -16.0F, -6.0F, 12.0F, 10.0F, 11.0F, new CubeDeformation(0.0F)).texOffs(46, 65).addBox(-5.0F, -8.0F, -5.0F, 10.0F, 7.0F, 8.0F, new CubeDeformation(0.0F)).texOffs(0, 60).addBox(-6.0F, -3.0F, -7.0F, 12.0F, 6.0F, 11.0F, new CubeDeformation(0.0F)).texOffs(86, 33).addBox(-6.0F, -1.0F, 4.0F, 12.0F, 4.0F, 2.0F, new CubeDeformation(0.0F)).texOffs(44, 46).addBox(-8.0F, 2.0F, -7.0F, 16.0F, 5.0F, 14.0F, new CubeDeformation(0.0F)), PartPose.offset(0.0F, 0.0F, 0.0F));PartDefinition Body_r1 = Body.addOrReplaceChild("Body_r1", CubeListBuilder.create().texOffs(0, 39).addBox(-8.0F, -9.0F, -8.0F, 16.0F, 11.0F, 13.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 22.0F, 0.0F, 0.0F, 0.0436F, 0.0F));PartDefinition Body_r2 = Body.addOrReplaceChild("Body_r2", CubeListBuilder.create().texOffs(0, 0).addBox(-9.0F, -4.0F, -9.0F, 18.0F, 8.0F, 15.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 9.0F, 0.0F, 0.0F, -0.0436F, 0.0F));PartDefinition Body_r3 = Body.addOrReplaceChild("Body_r3", CubeListBuilder.create().texOffs(88, 65).addBox(-3.0F, -3.0F, -3.5F, 6.0F, 6.0F, 6.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, -16.0F, -0.5F, 0.0F, 0.0436F, 0.0F));PartDefinition Body_r4 = Body.addOrReplaceChild("Body_r4", CubeListBuilder.create().texOffs(64, 81).addBox(-5.0F, -0.5F, -4.0F, 10.0F, 5.0F, 5.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, -13.5654F, -6.5679F, 1.0036F, 0.0F, 0.0F));PartDefinition RightArm = partdefinition.addOrReplaceChild("RightArm", CubeListBuilder.create(), PartPose.offsetAndRotation(-9.0F, -10.0F, -1.0F, -0.2182F, 0.0F, 0.0F));PartDefinition RightArm_r1 = RightArm.addOrReplaceChild("RightArm_r1", CubeListBuilder.create().texOffs(90, 46).addBox(-3.9816F, -2.2586F, -3.0789F, 4.0F, 6.0F, 6.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(2.0F, -1.759F, -0.7541F, 0.0436F, -0.1745F, 1.4399F));PartDefinition Rightbacktlib = RightArm.addOrReplaceChild("Rightbacktlib", CubeListBuilder.create(), PartPose.offset(0.0F, 2.0F, 0.0F));PartDefinition RightArm_r2 = Rightbacktlib.addOrReplaceChild("RightArm_r2", CubeListBuilder.create().texOffs(0, 94).addBox(-5.0F, -6.9981F, -5.0872F, 4.0F, 7.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(3.0F, 0.644F, 3.0686F, 0.1745F, 0.0F, 0.0F));PartDefinition Rightfrontlib = Rightbacktlib.addOrReplaceChild("Rightfrontlib", CubeListBuilder.create(), PartPose.offset(0.0F, 0.0F, 0.0F));PartDefinition RightArm_r3 = Rightfrontlib.addOrReplaceChild("RightArm_r3", CubeListBuilder.create().texOffs(0, 38).addBox(-0.1511F, -7.7229F, -1.5045F, 0.0F, 12.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-3.0422F, 18.6266F, -6.0745F, -0.3054F, 0.0436F, 0.0873F));PartDefinition RightArm_r4 = Rightfrontlib.addOrReplaceChild("RightArm_r4", CubeListBuilder.create().texOffs(6, 38).addBox(-1.1702F, 4.3202F, -1.0721F, 0.0F, 11.0F, 1.0F, new CubeDeformation(0.0F)).texOffs(10, 0).addBox(-2.1702F, 3.3202F, -1.0721F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)).texOffs(51, 3).addBox(-2.1702F, 3.3202F, -2.0721F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 6.8017F, -1.1584F, -0.3491F, 0.0F, 0.0873F));PartDefinition RightArm_r5 = Rightfrontlib.addOrReplaceChild("RightArm_r5", CubeListBuilder.create().texOffs(4, 39).addBox(0.8391F, -3.262F, -0.014F, 1.0F, 12.0F, 0.0F, new CubeDeformation(0.0F)).texOffs(9, 49).addBox(0.8391F, -3.262F, -0.014F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-1.0774F, 11.6115F, -4.6201F, -0.6545F, 0.0F, -0.1745F));PartDefinition RightArm_r6 = Rightfrontlib.addOrReplaceChild("RightArm_r6", CubeListBuilder.create().texOffs(2, 39).addBox(-0.1609F, -0.9749F, 0.5562F, 1.0F, 12.0F, 0.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-1.0774F, 11.6115F, -2.6201F, -0.3491F, 0.0F, -0.1745F));PartDefinition RightArm_r7 = Rightfrontlib.addOrReplaceChild("RightArm_r7", CubeListBuilder.create().texOffs(51, 0).addBox(-0.1609F, -2.6589F, 1.4355F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-1.0774F, 11.6115F, -4.6201F, -0.3491F, 0.0F, -0.1745F));PartDefinition RightArm_r8 = Rightfrontlib.addOrReplaceChild("RightArm_r8", CubeListBuilder.create().texOffs(0, 77).addBox(-2.0F, -6.6868F, -3.0746F, 3.0F, 10.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 6.8017F, -1.1584F, -0.3491F, 0.0F, 0.0F));PartDefinition nail = Rightfrontlib.addOrReplaceChild("nail", CubeListBuilder.create(), PartPose.offsetAndRotation(-1.3274F, 14.8615F, -4.6201F, -0.0436F, 0.0F, 0.0F));PartDefinition Rightnail_r1 = nail.addOrReplaceChild("Rightnail_r1", CubeListBuilder.create().texOffs(8, 38).addBox(-0.1281F, -0.5693F, -1.6828F, 0.0F, 11.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.25F, -3.25F, 0.0F, -0.1745F, -0.6109F, -0.4363F));PartDefinition RightArm_r9 = nail.addOrReplaceChild("RightArm_r9", CubeListBuilder.create().texOffs(51, 10).addBox(0.3164F, -2.4682F, -1.5852F, 1.0F, 2.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.25F, -3.25F, 0.0F, -0.3491F, 0.0F, -0.4363F));PartDefinition LeftArm = partdefinition.addOrReplaceChild("LeftArm", CubeListBuilder.create(), PartPose.offsetAndRotation(8.4442F, -8.8343F, -0.4302F, 0.2094F, 0.0F, 0.0F));PartDefinition LeftArm_r1 = LeftArm.addOrReplaceChild("LeftArm_r1", CubeListBuilder.create().texOffs(88, 85).addBox(-0.0164F, -3.2557F, -2.0027F, 4.0F, 6.0F, 6.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-0.5558F, -3.3343F, -0.4302F, 0.0436F, -0.2182F, -1.4399F));PartDefinition Leftlib = LeftArm.addOrReplaceChild("Leftlib", CubeListBuilder.create(), PartPose.offset(0.5558F, 2.5308F, -0.3245F));PartDefinition LeftArm_r2 = Leftlib.addOrReplaceChild("LeftArm_r2", CubeListBuilder.create().texOffs(17, 77).addBox(-2.0F, -5.4988F, -1.9302F, 4.0F, 7.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, -3.0F, 0.0F, -0.1745F, 0.0F, 0.0F));PartDefinition LeftArm_r3 = Leftlib.addOrReplaceChild("LeftArm_r3", CubeListBuilder.create().texOffs(16, 94).addBox(-1.0F, -9.076F, -3.2313F, 3.0F, 7.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 4.0829F, -5.6691F, -0.8727F, 0.0F, 0.0F));PartDefinition Leftfrontlib = Leftlib.addOrReplaceChild("Leftfrontlib", CubeListBuilder.create(), PartPose.offset(0.0F, 1.0F, -2.0F));PartDefinition LeftArm_r4 = Leftfrontlib.addOrReplaceChild("LeftArm_r4", CubeListBuilder.create().texOffs(0, 23).addBox(-2.0F, -9.076F, -3.2313F, 4.0F, 11.0F, 3.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 3.0829F, -3.6691F, -0.8727F, 0.0F, 0.0F));PartDefinition LeftArm_r5 = Leftfrontlib.addOrReplaceChild("LeftArm_r5", CubeListBuilder.create().texOffs(45, 46).addBox(0.4117F, 1.9822F, -3.162F, 1.0F, 3.0F, 2.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.3084F, 2.5147F, -3.6691F, -0.8727F, 0.0F, 0.3054F));PartDefinition LeftArm_r6 = Leftfrontlib.addOrReplaceChild("LeftArm_r6", CubeListBuilder.create().texOffs(45, 39).addBox(-1.0F, 2.0373F, -1.364F, 2.0F, 3.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 3.0829F, -3.6691F, -0.9599F, 0.0F, 0.0F));PartDefinition LeftArm_r7 = Leftfrontlib.addOrReplaceChild("LeftArm_r7", CubeListBuilder.create().texOffs(0, 0).addBox(-1.0F, -0.6472F, -6.2955F, 1.0F, 3.0F, 1.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(0.0F, 7.0829F, -3.6691F, -0.8727F, 0.0F, 0.0F));PartDefinition RightLeg = partdefinition.addOrReplaceChild("RightLeg", CubeListBuilder.create(), PartPose.offsetAndRotation(-1.9F, 12.0F, 0.0F, 0.192F, 0.0F, 0.0349F));PartDefinition RightLeg_r1 = RightLeg.addOrReplaceChild("RightLeg_r1", CubeListBuilder.create().texOffs(64, 91).addBox(-3.9698F, -6.9878F, -1.7911F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(1.9F, 5.0F, 0.0F, -0.0873F, 0.0F, 0.0F));PartDefinition LeftLeg = partdefinition.addOrReplaceChild("LeftLeg", CubeListBuilder.create(), PartPose.offsetAndRotation(1.9F, 12.0F, 0.0F, -0.1745F, 0.0F, -0.0349F));PartDefinition LeftLeg_r1 = LeftLeg.addOrReplaceChild("LeftLeg_r1", CubeListBuilder.create().texOffs(91, 6).addBox(-0.0302F, -8.9988F, -2.0F, 4.0F, 12.0F, 4.0F, new CubeDeformation(0.0F)), PartPose.offsetAndRotation(-1.9F, 7.0F, 0.0F, 0.1745F, 0.0F, 0.0F));return LayerDefinition.create(meshdefinition, 128, 128);}@Overridepublic void setupAnim(T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {this.Head.yRot = netHeadYaw * 0.007453292F;this.Head.xRot = headPitch * 0.007453292F;
//      this.beak.xRot = this.head.xRot;
//      this.beak.yRot = this.head.yRot;
//      this.redThing.xRot = this.head.xRot;
//      this.redThing.yRot = this.head.yRot;
//      this.body.xRot = ((float)Math.PI / 2F);this.LeftArm.xRot = Mth.cos(limbSwing * 0.7662F) * 1.3F * limbSwingAmount;this.RightArm.xRot = Mth.cos(limbSwing * 0.7662F + (float)Math.PI) * 1.3F * limbSwingAmount;this.LeftLeg.xRot = Mth.cos(limbSwing * 0.5662F) * 1.4F * limbSwingAmount;this.RightLeg.xRot = Mth.cos(limbSwing * 0.5662F + (float)Math.PI) * 1.4F * limbSwingAmount;}public void setRotationAngle(ModelPart ModelPart, float x, float y, float z) {ModelPart.xRot = x;ModelPart.yRot= y;ModelPart.zRot = z;}@Overridepublic void renderToBuffer(PoseStack poseStack, VertexConsumer buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {Head.render(poseStack, buffer, packedLight, packedOverlay);Body.render(poseStack, buffer, packedLight, packedOverlay);RightArm.render(poseStack, buffer, packedLight, packedOverlay);LeftArm.render(poseStack, buffer, packedLight, packedOverlay);RightLeg.render(poseStack, buffer, packedLight, packedOverlay);LeftLeg.render(poseStack, buffer, packedLight, packedOverlay);}
}

为了让我们的生物在游戏中可以显示出来,我们需要编写生物的渲染文件

在render文件夹中新建渲染类(以RenderRe8Dimi.java为例)
RenderRe8Dimi.java

package com.joy187.re8joymod.entity.render;import com.joy187.re8joymod.Main;
import com.joy187.re8joymod.entity.EntityRe8Dimi;
import com.joy187.re8joymod.entity.model.ModelRe8Dimi;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.entity.MobRenderer;
import net.minecraft.resources.ResourceLocation;public class RenderRe8Dimi extends MobRenderer<EntityRe8Dimi, ModelRe8Dimi<EntityRe8Dimi>> {//注意这个路径,要和上面model文件中的路径保持一致public static final ResourceLocation TEXTURE = new ResourceLocation(Main.MOD_ID, "textures/entity/re8dimi.png");public RenderRe8Dimi(EntityRendererProvider.Context manager) {super(manager, new ModelRe8Dimi<>(manager.bakeLayer(ModelRe8Dimi.LAYER_LOCATION)), 0.7F);}@Overridepublic ResourceLocation getTextureLocation(EntityRe8Dimi p_110775_1_) {return TEXTURE;}
}

2.在init包中新建一个EntityInit类用于初始化我们所有的生物

EntityInit.java

package com.joy187.re8joymod.init;import com.joy187.re8joymod.Main;
import com.joy187.re8joymod.entity.EntityRe8Dimi;import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;public class EntityInit {public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITIES,Main.MOD_ID);//我们的生物类型为MONSTER(怪物),你可以定义其他类型MOB等,两个字符串要一样比如"re8dimi"public static final RegistryObject<EntityType<EntityRe8Dimi>> RE8DIMI = ENTITY_TYPES.register("re8dimi",() -> EntityType.Builder.of(EntityRe8Dimi::new, MobCategory.MONSTER).sized(0.8f,3.0f).setTrackingRange(30).build(new ResourceLocation(Main.MOD_ID, "re8dimi").toString()));//你可以往下续写
}

3.新建一个ClientModEventSubscriber类用于提交我们的渲染信息

ClientModEventSubscriber.java
package com.joy187.re8joymod;import net.minecraftforge.fml.common.Mod;import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;import com.joy187.re8joymod.entity.EntityRe8Dimi;
import com.joy187.re8joymod.entity.model.ModelRe8Dimi;
import com.joy187.re8joymod.entity.render.RenderRe8Dimi;
import com.joy187.re8joymod.init.EntityInit;import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.EntityRenderersEvent;
import net.minecraftforge.event.entity.EntityAttributeCreationEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;@Mod.EventBusSubscriber(modid = Main.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ClientModEventSubscriber
{//将所有的生物的皮肤贴图信息写在这个函数里,有几个写几个@SubscribeEventpublic static void onRegisterLayers(EntityRenderersEvent.RegisterLayerDefinitions event) {event.registerLayerDefinition(ModelRe8Dimi.LAYER_LOCATION, ModelRe8Dimi::createBodyLayer);}//将所有的生物的渲染信息写在这个函数里,有几个写几个@SubscribeEventpublic static void onRegisterRenderer(EntityRenderersEvent.RegisterRenderers event) {event.registerEntityRenderer(EntityInit.RE8DIMI.get(), RenderRe8Dimi::new);}//将所有的生物的属性信息写在这个函数里,有几个写几个@SubscribeEventpublic static void onAttributeCreate(EntityAttributeCreationEvent event) {event.put(EntityInit.RE8DIMI.get(), EntityRe8Dimi.prepareAttributes().build());}}

4.在Main.java中添加:

 public Main() {IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();ItemInit.ITEMS.register(bus);BlockInit.BLOCKS.register(bus);//把生物初始化语句加入EntityInit.ENTITY_TYPES.register(bus);MinecraftForge.EVENT_BUS.register(this);}

5.在textures包下新建一个entity文件夹存放我们的生物皮肤贴图,将.png贴图放入其中:

在en_us.lang文件中添加游戏中的生物名称

"entity.re8joymod.re8dimi": "Alcina Dimitrescu",

怪物掉落物:

在resources\data\re8joymod\loot_tables下新建一个entities文件夹 -> 在文件夹中新建我们的生物掉落物.json文件(文件名称与EntityInit.java中保持一致)

{"type": "minecraft:entity","pools": [{"rolls": 1.0,       "bonus_rolls": 0.0,"entries": [{"type": "item","name": "re8joymod:blackfeather", //掉落物格式: 模组名称:物品名称"weight": 6,"functions": [{"function": "set_count",    //掉落个数"count": {"min": 0,   //最少掉几个"max": 2    //最多掉几个}},{"function": "looting_enchant","count": {"min": 0,"max": 1}}]},{"type": "item","weight": 5,"name": "minecraft:totem_of_undying",   //原版掉落物格式: minecraft:物品名称"functions": [{"function": "set_count","count": {"min": 2,"max": 3}}]},{"type": "item","weight": 5,"name": "minecraft:nether_star","functions": [{"function": "set_count","count": {"min": 3,"max": 5}}]}]},{"name": "pool1","rolls": 1,"entries": [{"type": "item","name": "minecraft:bone","weight": 10},{"type": "item","name": "minecraft:ghast_tear","weight": 4},{"type": "item","weight": 5,"name": "minecraft:nether_star","functions": [{"function": "set_count","count": {"min": 3,"max": 5}}]}]}]
}

6.生物蛋制作

在ItemInit中添加:

        //刷怪蛋格式:ForgeSpawnEggItem(生物类,颜色1,颜色2,放在哪个物品栏)
public static final RegistryObject<Item> THIEF_EGG = ITEMS.register("re8dimi_spawn_egg", () -> new ForgeSpawnEggItem(EntityInit.RE8DIMI, 9577503, 13423070, new Item.Properties().tab(Main.TUTORIAL_TAB)));

在resources\assets\re8joymod\models\item中新建一个刷怪蛋.json文件(名称与ItemInit中的名称保持一致)

re8dimi_spawn_egg.json
{"parent": "item/template_spawn_egg"
}

在en_us.lang中添加语言信息:

"item.re8joymod.re8dimi_spawn_egg": "Alcina Dimitrescu Spawn Egg",

7.保存所有文件,刷新项目 -> 启动游戏

我们的Boss成功生成!

Minecraft 1.18.1、1.18.2模组开发 03.生物实体相关推荐

  1. Minecraft 1.19.2 Forge模组开发 03.动画生物实体

    1.12.2动画生物实体教程 1.16.5动画生物实体教程 1.18.2动画生物实体教程 效 果 展 示 效果展示 效果展示 我们本次尝试在1.19.2中添加一个能够具有各种动画效果动作的生物实体. ...

  2. Minecraft 1.19.2 Fabric模组开发 03.动画生物实体

    我们本次尝试在1.19.2 Fabric中添加一个能够具有各种动画效果动作的生物实体. 效果展示 效果展示 效果展示 1.首先,为了实现这些动画效果,我们需要首先使用到一个模组:geckolib(下载 ...

  3. Minecraft 1.19.2 Forge模组开发 08.生物生成

    Minecraft 1.18.2 生物生成 我们今天尝试在1.19中生成模组中的生物 效果演示效果演示效果演示 1.在你的项目主类中的commonSetup方法中添加模组中生物的生成规则(可参考文末M ...

  4. Minecraft 1.18.1、1.18.2模组开发 22.方块实体(BlockEntity)

    Minecraft1.12.2 方块实体教程 MC中有许多很有趣的方块实体如旗帜.钟.附魔台-我们今天在1.18的版本下实现一个类似于熔炉的方块实体. 1.在blocks包中新建一个我们的方块实体包v ...

  5. Minecraft 1.18.1、1.18.2模组开发 10.生物生成

    我们今天来实现一下在世界中生成我们的模组生物 1.Java包中新建world包 -> world包中新建gen包 -> gen包中新建ModEntityGeneration类 ModEnt ...

  6. Minecraft 1.16.5模组开发(四十七) 动画生物实体

    1.18.2动画生物实体教程 今天我们尝试在1.16.5中添加一个能够做各种动作的生物实体,由于使用的是geckolib进行开发,所以代码方面和1.18.2没有太大差别. 1.首先,为了实现这些效果, ...

  7. Minecraft 1.19.2 Forge模组开发 04.动画效果物品

    我们本次实现一个具有动画效果的物品,本次演示的模型代码均在文末给出 效果演示效果演示效果演示 首先,请确保你的开发包中引入了geckolib依赖,相关教程请参考:Minecraft 1.19.2 Fo ...

  8. Minecraft 1.18.1、1.18.2模组开发 02.方块和物品

    今天我们在1.18.1版本下制作属于自己的方块和物品 1.新建init文件夹 -> init包中新建BlockInit.java和ItemInit.java BlockInit.java pac ...

  9. Minecraft 1.18.1、1.18.2模组开发 05.发射器+投掷物

    1.12.2的霰弹枪教程:Minecraft 1.12.2模组开发(二十三) 霰弹枪! 1.16.5版本的投掷物教程:Minecraft 1.16.5模组开发(三十二) 自定义投掷物品实体 本期我们来 ...

最新文章

  1. 光流估计 liteflownet3
  2. USB接口定义(Z)
  3. 解决 spring-cloud-starter-zipkin 启动错误
  4. 控制台编写JAVA程序教程_写一个java程序的步骤是什么?写java程序技巧
  5. 微信果断出手 将封禁拼团砍价链接,网友:终于可以清静了
  6. 第三:Python发送邮件时中文附件下载乱码
  7. Linux用户管理(六)Linux磁盘管理
  8. linux运行隐藏脚本,linux 下隐藏进程的一种方法及遇到的坑
  9. 如何利用迅雷下载百度云?
  10. svn server服务器搭建
  11. html常用语言代码大全,常用的html代码大全
  12. 主板放电之后 mac 无法正常启动之谜
  13. bind9 域名劫持_域名劫持会怎样?如何解决域名劫持
  14. php disable hugepage,禁用Transparent Huge Pages
  15. 大数据开发学习脑图+学习路线清晰的告诉你!月薪30K很轻松
  16. WFP实现侧边栏导航菜单
  17. 工商银行总行营业厅管理软件设置视频教程
  18. 苹果手机里的照片导入电脑
  19. 数据库系统原理--------层次模型
  20. Unity Shader PostProcessing - 5 - PixelSyle 像素化风格

热门文章

  1. 推荐workFlowy
  2. OLED 4K与QLED 8K的彩电之争: 时代、消费者的选择
  3. python绘制三维散点图(已验证)
  4. Android有未接来电后处理(判断未接来电)
  5. python模拟发红包_Python编写简易发红包程序
  6. What Is the Space of Attenuation Coefficients in Underwater Computer Vision? --中文翻译
  7. 红米k30至尊版和红米k30s至尊版参数对比哪个更值得入手
  8. Linux命令之删除空目录rmdir
  9. vue实现全局消息提醒功能(vue-extend)
  10. 【VScode远程连接虚拟机(ubuntu)】