AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

Minecraft 1.19.2 Forge模组开发 10.3D动画盔甲

作者: 作者的头像   GRID ,  2023-01-18 17:48:45 ,  所有人可见 ,  阅读 811


3


Minecraft 1.16.5模组开发3D盔甲

Minecraft 1.12.2模组开发3D盔甲

Minecraft 1.18.2模组开发3D动画盔甲

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

hat.gif
$$效果演示$$

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

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

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')

}

之后我们重新构建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栏,点击进去:

ani.jpg

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

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

cc.png

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

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

ChandlierArmorItem.java

package net.joy187.joyggd.item.armor;

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

import net.joy187.joyggd.Main;
import net.joy187.joyggd.init.ItemInit;
import net.joy187.joyggd.item.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.item.Item.Properties;
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 ChandlierArmorItem extends GeoArmorItem implements IAnimatable{
    private AnimationFactory factory = new AnimationFactory(this);

    public ChandlierArmorItem(ArmorMaterial materialIn, EquipmentSlot slot, Properties builder) {
        super(materialIn, slot, builder.tab(Main.ITEM_TAB));
    }

    //动画状态机,判断每个时刻我们的盔甲的动画状态
    @SuppressWarnings("unused")
    private <P extends IAnimatable> PlayState predicate(AnimationEvent<P> event) {
        List<EquipmentSlot> slotData = event.getExtraDataOfType(EquipmentSlot.class);
        List<ItemStack> stackData = event.getExtraDataOfType(ItemStack.class);
        LivingEntity livingEntity = event.getExtraDataOfType(LivingEntity.class).get(0);

        if(!event.isMoving())
        {
            event.getController().setAnimation(new AnimationBuilder().addAnimation("animation.chandlier.rotate", true));
        }

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


        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()));

            //我们本次只制作一个头盔,所以subList为(5,6)
            // elements 2 to 6 are the armor so we take the sublist. Armorlist now only
            // contains the 4 armor slots
            List<Item> armorList = equipmentList.subList(5, 6);

            boolean isWearingAll = armorList
                    .containsAll(Arrays.asList(ItemInit.CHANDLIER.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;
    }

    //穿上盔甲后是否给予我们特殊效果
//    @Override
//    public void onArmorTick(ItemStack stack, Level world, Player player) {
//        if(!world.isClientSide()) {
//            if(!player.getInventory().getArmor(3).isEmpty()) {
//                MobEffectInstance mapStatusEffect1 = new MobEffectInstance(MobEffects.MOVEMENT_SPEED, 20*60, 1);
//                MobEffectInstance mapStatusEffect2 = new MobEffectInstance(MobEffects.NIGHT_VISION, 20*60, 1);
//
//                ArmorItem helmet = ((ArmorItem)player.getInventory().getArmor(3).getItem());
//                if(helmet.getMaterial() == CustomArmorMaterial.ARMOR_MATERIAL_ADASUIT) {
//                    boolean hasPlayerEffect = player.hasEffect(mapStatusEffect1.getEffect());
//                    if(!hasPlayerEffect) {
//                        player.addEffect(new MobEffectInstance(mapStatusEffect1.getEffect(),mapStatusEffect1.getDuration(), mapStatusEffect1.getAmplifier()));
//                        player.addEffect(new MobEffectInstance(mapStatusEffect2.getEffect(),mapStatusEffect2.getDuration(), mapStatusEffect2.getAmplifier()));
//                    }
//                }
//              //player.addEffect(new MobEffectInstance(EffectInit.ZENHEART.get(), 100, 1));
//            }
//        }
//    }

}

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

ModelChandlier.java

package net.joy187.joyggd.item.armor.model;


import net.joy187.joyggd.Main;
import net.joy187.joyggd.item.armor.ChandlierArmorItem;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib3.model.AnimatedGeoModel;


public class ModelChandlier extends AnimatedGeoModel<ChandlierArmorItem> {
    //盔甲模型文件地址
    @Override
    public ResourceLocation getModelResource(ChandlierArmorItem object) {
        return new ResourceLocation(Main.MOD_ID, "geo/chandlier.geo.json");
    }

    //盔甲材质文件地址
    @Override
    public ResourceLocation getTextureResource(ChandlierArmorItem object) {
        return new ResourceLocation(Main.MOD_ID, "textures/models/armor/chandlier_layer_1.png");
    }

    //盔甲动画文件地址
    @Override
    public ResourceLocation getAnimationResource(ChandlierArmorItem animatable) {
        return new ResourceLocation(Main.MOD_ID, "animations/chandlier.animation.json");
    }
}

之后我们需要在armor包中新建render包->render包中新建我们的盔甲的渲染类RenderChandlier:

RenderChandlier.java

package net.joy187.joyggd.item.armor.render;


import net.joy187.joyggd.item.armor.ChandlierArmorItem;
import net.joy187.joyggd.item.armor.model.ModelChandlier;
import software.bernie.geckolib3.renderers.geo.GeoArmorRenderer;


public class RenderChandlier extends GeoArmorRenderer<ChandlierArmorItem> {
    //渲染盔甲穿在身上的每一个部位的效果
    public RenderChandlier() {
        super(new ModelChandlier());
        //这里要和第二步你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{

    @SubscribeEvent
    public static void registerRenderers(final EntityRenderersEvent.AddLayers event) {
        //渲染类进行注册
        GeoArmorRenderer.registerArmorRenderer(ChandlierArmorItem.class, RenderChandlier::new);
    }
}

5.在ItemInit类中将我们的盔甲进行声明,盔甲属性请参考1.18的教程,一模一样:1.18.2 盔甲套装:

ItemInit.java

    //头盔
    public static final RegistryObject<ChandlierArmorItem> CHANDLIER = ITEMS.register("chandlier",
            () -> new ChandlierArmorItem(CustomArmorMaterial.ARMOR_MATERIAL_CHANDLIER, EquipmentSlot.HEAD, new Item.Properties()));



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

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

"item.joyggd.chandlier":"Chandlier",

在models\item包中添加所有盔甲的模型文件:

chandlier.json

{
  "parent":"minecraft:item/generated",
  "textures":{
    "layer0":"joyggd:item/chandlier"
  }
}

在textures\item中添加盔甲的手持贴图:

39383_761f3eec0f-crr2.jpg

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

39383_dcd4c5260f-crr3.jpg

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

360截图20230118174221226.jpg

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

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

2023-01-18_17.45.46.png

1 评论


用户头像
儒雅随和_t   2023-01-18 17:49         踩      回复

硬核


你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息