Minecraft 1.18.1、1.18.2模组开发 23.3D动画盔甲制作

Minecraft 1.16.5模组开发3D盔甲

Minecraft 1.12.2模组开发3D盔甲

我们本次在1.18.2的版本中实现具有动画效果的3D盔甲

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

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

repositories {

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

}

cr4.png

之后我们重新构建gradle项目

cr5.png

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

Main.java

	public Main() {
		IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();

		ItemInit.ITEMS.register(bus);


        //添加GeckoLib初始化函数
        GeckoLib.initialize();


		MinecraftForge.EVENT_BUS.register(this);
	}

2.之后,与之前的教程一样,我们需要在blockbench中制作一个模组中的3D盔甲:

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

cr6.png

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

cr7.png

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

crr.jpg

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

注:我们的盔甲的要完全按照这种进行制作:

crr1.jpg

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

cc.png

3.模型制作完成,接下来需要制作我们的盔甲类

在items包中新建armor包 -> armor包中新建我们的套装类HeisensuitArmorItem

HeisensuitArmorItem.java

package com.joy187.re8joymod.items.armor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.google.common.collect.ImmutableMap;
import com.joy187.re8joymod.Main;
import com.joy187.re8joymod.init.EffectInit;
import com.joy187.re8joymod.init.ItemInit;
import com.joy187.re8joymod.util.CustomArmorMaterial;

import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.decoration.ArmorStand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.ArmorMaterial;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
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;
import software.bernie.geckolib3.item.GeoArmorItem;


public class HeisensuitArmorItem extends GeoArmorItem implements IAnimatable{
	private AnimationFactory factory = new AnimationFactory(this);

	public HeisensuitArmorItem(ArmorMaterial materialIn, EquipmentSlot slot, Properties builder) {
		super(materialIn, slot, builder.tab(Main.TUTORIAL_TAB));
	}
	
    //动画状态机,判断每个时刻我们的盔甲的动画状态
	@SuppressWarnings("unused")
	private <P extends IAnimatable> PlayState predicate(AnimationEvent<P> event) {
		// This is all the extradata this event carries. The livingentity is the entity
		// that's wearing the armor. The itemstack and equipmentslottype are self
		// explanatory.
		List<EquipmentSlot> slotData = event.getExtraDataOfType(EquipmentSlot.class);
		List<ItemStack> stackData = event.getExtraDataOfType(ItemStack.class);
		LivingEntity livingEntity = event.getExtraDataOfType(LivingEntity.class).get(0);

		// Always loop the animation but later on in this method we'll decide whether or
		// not to actually play it
		event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.heisensuit.idle", true));

		// If the living entity is an armorstand just play the animation nonstop
		if (livingEntity instanceof ArmorStand) {
			return PlayState.CONTINUE;
		}

		// The entity is a player, so we want to only play if the player is wearing the
		// full set of armor
		else if (livingEntity instanceof Player) {
			Player player = (Player) livingEntity;

			// Get all the equipment, aka the armor, currently held item, and offhand item
			List<Item> equipmentList = new ArrayList<>();
			player.getAllSlots().forEach((x) -> equipmentList.add(x.getItem()));

			// 包含四个盔甲位置
			List<Item> armorList = equipmentList.subList(2, 6);
            
            //如果玩家穿上了所有的套装就会播放相应的动画
			// Make sure the player is wearing all the armor. If they are, continue playing
			// the animation, otherwise stop
			//ItemInit.HEISEN_BOOTS.get(), ItemInit.HEISEN_LEGGINGS.get(),ItemInit.HEISEN_CHEST.get(), ItemInit.HEISEN_HEAD.get()
			boolean isWearingAll = armorList
					.containsAll(Arrays.asList(ItemInit.HEISEN_BOOTS.get(), ItemInit.HEISEN_LEGG.get()
							,ItemInit.HEISEN_SUIT.get(), ItemInit.HEISEN_HEAD.get()));
			return isWearingAll ? PlayState.CONTINUE : PlayState.STOP;
		}
		return PlayState.STOP;
	}
	
	//将我们的待机动画进行注册
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void registerControllers(AnimationData data) {
		data.addAnimationController(new AnimationController(this, "controller", 20, this::predicate));
	}

	@Override
	public AnimationFactory getFactory() {
		return this.factory;
	}
	
    private static final Map<ArmorMaterial, MobEffectInstance> MATERIAL_TO_EFFECT_MAP =
            (new ImmutableMap.Builder<ArmorMaterial, MobEffectInstance>())
                    .put(CustomArmorMaterial.ARMOR_MATERIAL_HEISENSUIT,
                            new MobEffectInstance(MobEffects.DAMAGE_RESISTANCE, 100, 1)).build();
    
    //穿上后给予效果
    @Override
    public void onArmorTick(ItemStack stack, Level world, Player player) {
        if(!world.isClientSide()) {
            //穿上头盔就给予一个药水效果
            if(!player.getInventory().getArmor(3).isEmpty()) {
                MobEffectInstance mapStatusEffect1 = new MobEffectInstance(MobEffects.DAMAGE_RESISTANCE, 100, 2);
                ArmorItem helmet = ((ArmorItem)player.getInventory().getArmor(3).getItem());
                if(helmet.getMaterial() == CustomArmorMaterial.ARMOR_MATERIAL_HEISENSUIT) {
                    boolean hasPlayerEffect = player.hasEffect(mapStatusEffect1.getEffect());
                    if(!hasPlayerEffect) {
                        player.addEffect(new MobEffectInstance(mapStatusEffect1.getEffect(),mapStatusEffect1.getDuration(), mapStatusEffect1.getAmplifier()));
                    }
                }
            }
            //穿上胸甲就给予一个药水效果
            if(!player.getInventory().getArmor(2).isEmpty()) {
                MobEffectInstance mapStatusEffect2 = new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 100, 1);

                ArmorItem breastplate = ((ArmorItem)player.getInventory().getArmor(2).getItem());
                if(breastplate.getMaterial() == CustomArmorMaterial.ARMOR_MATERIAL_HEISENSUIT) {
                    boolean hasPlayerEffect = player.hasEffect(mapStatusEffect2.getEffect());
                    if(!hasPlayerEffect) {
                        player.addEffect(new MobEffectInstance(mapStatusEffect2.getEffect(),mapStatusEffect2.getDuration(), mapStatusEffect2.getAmplifier()));
                    }
                }
            }   
            //穿上护腿就给予一个药水效果
            if(!player.getInventory().getArmor(1).isEmpty()) {
                MobEffectInstance mapStatusEffect3 = new MobEffectInstance(MobEffects.SLOW_FALLING, 100, 1);

                ArmorItem leggings = ((ArmorItem)player.getInventory().getArmor(1).getItem());
                if(leggings.getMaterial() == CustomArmorMaterial.ARMOR_MATERIAL_HEISENSUIT) {
                    boolean hasPlayerEffect = player.hasEffect(mapStatusEffect3.getEffect());
                    if(!hasPlayerEffect) {
                        player.addEffect(new MobEffectInstance(mapStatusEffect3.getEffect(),mapStatusEffect3.getDuration(), mapStatusEffect3.getAmplifier()));
                    }
                }
            }
            //穿上靴子就给予一个药水效果
            if(!player.getInventory().getArmor(0).isEmpty()) {
                MobEffectInstance mapStatusEffect4 = new MobEffectInstance(MobEffects.MOVEMENT_SPEED, 100, 0);
                ArmorItem boots = ((ArmorItem)player.getInventory().getArmor(0).getItem());
                if(boots.getMaterial() == CustomArmorMaterial.ARMOR_MATERIAL_HEISENSUIT) {
                    boolean hasPlayerEffect = player.hasEffect(mapStatusEffect4.getEffect());
                    if(!hasPlayerEffect) {
                        player.addEffect(new MobEffectInstance(mapStatusEffect4.getEffect(),mapStatusEffect4.getDuration(), mapStatusEffect4.getAmplifier()));
                    }
                }
            }
        }
    }

}
之后我们需要在armor包中新建model包->model包中新建我们的盔甲的模型类ModelHeisensuit

ModelHeisensuit.java

package com.joy187.re8joymod.items.armor.model;

import com.joy187.re8joymod.Main;
import com.joy187.re8joymod.items.armor.HeisensuitArmorItem;

import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib3.model.AnimatedGeoModel;


public class ModelHeisensuit extends AnimatedGeoModel<HeisensuitArmorItem> {
	
	//盔甲模型文件地址
	@Override
	public ResourceLocation getModelLocation(HeisensuitArmorItem object) {
		return new ResourceLocation(Main.MOD_ID, "geo/heisensuit.geo.json");
	}
	
	//盔甲材质文件地址
	@Override
	public ResourceLocation getTextureLocation(HeisensuitArmorItem object) {
		return new ResourceLocation(Main.MOD_ID, "textures/models/armor/heisensuit_layer_1.png");
	}

	//盔甲动画文件地址
	@Override
	public ResourceLocation getAnimationFileLocation(HeisensuitArmorItem animatable) {
		return new ResourceLocation(Main.MOD_ID, "animations/heisensuit.animation.json");
	}
}
之后我们需要在armor包中新建render包->render包中新建我们的盔甲的渲染类ModelHeisensuit

RenderHeisensuit.java

package com.joy187.re8joymod.items.armor.render;

import com.joy187.re8joymod.items.armor.HeisensuitArmorItem;
import com.joy187.re8joymod.items.armor.model.ModelHeisensuit;

import software.bernie.geckolib3.renderers.geo.GeoArmorRenderer;


public class RenderHeisensuit extends GeoArmorRenderer<HeisensuitArmorItem> {
    //渲染盔甲穿在身上的每一个部位的效果
	public RenderHeisensuit() {
		super(new ModelHeisensuit());

		//这里要和第二步你blockbench中建模的名称一一对应
		this.headBone = "Head";
		this.bodyBone = "chestplate";
		this.rightArmBone = "rightArm";
		this.leftArmBone = "leftArm";
		this.rightLegBone = "rightLeg";
		this.leftLegBone = "leftLeg";
		this.rightBootBone = "rightBoot";
		this.leftBootBone = "leftBoot";
	}
}

4.在ClientModEventSubscriber类中将我们的盔甲渲染类进行注册:

ClientModEventSubscriber.java

@Mod.EventBusSubscriber(modid = Main.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ClientModEventSubscriber extends ModEventSubscriber{
	
    @OnlyIn(Dist.CLIENT)
	@SubscribeEvent
	public static void registerRenderers(final EntityRenderersEvent.AddLayers event) {
		
		//渲染类进行注册
		GeoArmorRenderer.registerArmorRenderer(HeisensuitArmorItem.class, new RenderHeisensuit());
	}
}

5.在ItemInit类中将我们的盔甲进行声明,盔甲属性请参考之前的教程1.18.2 盔甲套装

ItemInit.java

    //头盔
	public static final RegistryObject<HeisensuitArmorItem> HEISEN_HEAD = ITEMS.register("heisenhead",
			() -> new HeisensuitArmorItem(CustomArmorMaterial.ARMOR_MATERIAL_HEISENSUIT, EquipmentSlot.HEAD, new Item.Properties()));
	//胸甲
	public static final RegistryObject<HeisensuitArmorItem> HEISEN_SUIT = ITEMS.register("heisensuit",
			() -> new HeisensuitArmorItem(CustomArmorMaterial.ARMOR_MATERIAL_HEISENSUIT, EquipmentSlot.CHEST, new Item.Properties()));
	//护腿
	public static final RegistryObject<HeisensuitArmorItem> HEISEN_LEGG = ITEMS.register("heisenlegg",
			() -> new HeisensuitArmorItem(CustomArmorMaterial.ARMOR_MATERIAL_HEISENSUIT, EquipmentSlot.LEGS, new Item.Properties()));
	//靴子
	public static final RegistryObject<HeisensuitArmorItem> HEISEN_BOOTS = ITEMS.register("heisenboots",
			() -> new HeisensuitArmorItem(CustomArmorMaterial.ARMOR_MATERIAL_HEISENSUIT, EquipmentSlot.FEET, new Item.Properties()));

6.代码部分结束,之后来到材质包制作环节:

resources\assets\你的modid中的lang包中的en_us.json添加盔甲的英文名称:

  "item.re8joymod.heisenhead":"H",
  "item.re8joymod.heisensuit":"H",
  "item.re8joymod.heisenlegg":"Hei",
  "item.re8joymod.heisenboots":"Heis",
models\item包中添加所有盔甲的模型文件:
头盔

heisenhead.json

{
	"parent": "item/generated",
	"textures": {
		"layer0": "re8joymod:item/heisenhead"
	}
}
胸甲

heisensuit.json

{
	"parent": "item/generated",
	"textures": {
		"layer0": "re8joymod:item/heisensuit"
	}
}
护腿

heisenlegg.json

{
	"parent": "item/generated",
	"textures": {
		"layer0": "re8joymod:item/heisenlegg"
	}
}
靴子

heisenboots.json

{
	"parent": "item/generated",
	"textures": {
		"layer0": "re8joymod:item/heisenboots"
	}
}
textures\item中添加盔甲的手持贴图:

crr2.jpg

textures\models\armor中添加盔甲的穿戴后贴图:

crr3.jpg

assets\minecraft\textures\models\armor中同样添加我们的穿戴后贴图:

crr4.jpg

新建一个geo包和animation包,把第二步中的模型和动画文件分别放进去

cr10.png

8.保存所有文件 -> 进行测试:

穿上盔甲,如果可以正常显示,就说明我们成功了!

suiton.png

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay_fearless

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值