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

本教程详细介绍了如何在Minecraft 1.19.2中创建一个拥有动画效果的生物实体。首先,你需要下载并添加geckolib模组的依赖,然后在Blockbench中制作生物模型和动画。接着,编写生物实体类,定义其行为和AI,包括攻击和飞行动画。创建模型类和渲染类,注册生物实体和其属性。最后,设置生物的刷怪蛋和战利品掉落。通过这个过程,你可以为你的Minecraft mod添加生动的动画生物。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.12.2动画生物实体教程

1.16.5动画生物实体教程

1.18.2动画生物实体教程

在这里插入图片描述

效 果 展 示 效果展示

我们本次尝试在1.19.2中添加一个能够具有各种动画效果动作的生物实体。

1.首先,为了实现这些动画效果,我们需要首先使用到一个模组:geckolib(下载地址)

找到项目的build.gradle文件,在repositoriesdependencies中添加依赖。

repositories {

    //添加这个
    maven { url 'https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/' }
    
}
dependencies {
    minecraft 'net.minecraftforge:forge:1.19.2-43.1.1'
       
    //添加这个
    implementation fg.deobf('software.bernie.geckolib:geckolib-forge-1.19:3.1.36')

}

cr1.jpg

之后点击Load Gradle按钮重新构建项目

CR.jpg

构建好了项目后在项目的Main类中添加一句geckolib的初始化语句:

Main.java

    public Main()
    {
        IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
        // Register the commonSetup method for modloading
        bus.addListener(this::commonSetup);
        bus.addListener(this::setup);
        ItemInit.ITEMS.register(bus);
        BlockInit.BLOCKS.register(bus);
        EntityInit.ENTITY_TYPES.register(bus);

        
        //添加这个
        GeckoLib.initialize();

        MinecraftForge.EVENT_BUS.register(this);
    }

2.之后,与之前的教程一样,我们需要在blockbench中制作一个模组中的生物实体:

进入软件后我们要找到一个插件按钮,然后再搜索栏中输入GeckoLib Animation Utils,并下载这个插件

cr6.png

将我们制作好的生物实体进行模型转换工作,找到Convert Project,之后选择Geckolib Animated Model

cr7.png

在这之后,你会发现你的生物实体栏多了一个Animate栏,点击进去:

sam.jpg

具体动作制作的视频:Blockbench动画制作

在制作好所有的动画后我们导出模型和动画json文件。

cc.png

3.模型制作完成,接下来需要制作生物实体类,因为我们的生物的动作有很多,所以要在生物的不同状态时做出对应的动作。

EntitySamca.java

package com.joy187.re8joymod.entity;

import java.util.EnumSet;

import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.goal.FloatGoal;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal;
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.monster.Monster;
import net.minecraft.world.entity.monster.Vex;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.raid.Raider;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.PlayState;
import software.bernie.geckolib3.core.builder.AnimationBuilder;
import software.bernie.geckolib3.core.controller.AnimationController;
import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
import software.bernie.geckolib3.core.manager.AnimationData;
import software.bernie.geckolib3.core.manager.AnimationFactory;

public class EntitySamca extends Vex implements IAnimatable{

	private AnimationFactory factory = new AnimationFactory(this);

	public EntitySamca(EntityType<? extends Vex> type, Level worldIn) {
        super(type, worldIn);
        this.xpReward = 20;
    }

	public static AttributeSupplier.Builder prepareAttributes() {
		return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 35.0D).
				add(Attributes.ATTACK_DAMAGE, 8.5D).
		    	add(Attributes.MOVEMENT_SPEED, 0.28D).
		        add(Attributes.KNOCKBACK_RESISTANCE, 0.15D);
	}

	protected void registerGoals() {
		      super.registerGoals();
		      this.goalSelector.addGoal(0, new FloatGoal(this));
		      this.goalSelector.addGoal(4, new ChargeAttackGoal());
		      this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 3.0F, 1.0F));
		      this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F));
		      this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, Raider.class)).setAlertOthers());
		      this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true));
		      //this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, EntityEthan.class, true));
		      this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));

	}
	
    //我们生物的AI,决定使用哪种攻击方式
    class ChargeAttackGoal extends Goal {
        public ChargeAttackGoal() {
            this.setFlags(EnumSet.of(Flag.MOVE));
        }

        public boolean canUse() {
            if (EntitySamca.this.getTarget() != null && !EntitySamca.this.getMoveControl()