Minecraft 1.19.2 Fabric模组开发 08.3D动画盔甲

news2024/11/14 17:38:56

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

hat.gif
效果演示 效果演示 效果演示

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'

    //添加这个
    modImplementation 'software.bernie.geckolib:geckolib-fabric-1.19:3.1.18'

}

之后我们重新构建gradle项目

cr5.png

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

ModMain.java

	@Override
	public void onInitialize() {
		ModConfigs.registerConfigs();
		
		ItemInit.registerModItems();
		BlockInit.registerModBlocks();
		EffectInit.registerEffects();
		SoundInit.registerSounds();
		BlockEntityInit.registerAllBlockEntities();
		//初始化语句
		GeckoLib.initialize();


	}

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

import net.joy187.joyggd.init.ItemInit;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ArmorMaterial;
import net.minecraft.item.Item;
import software.bernie.example.registry.ItemRegistry;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ChandlierArmorItem extends ArmorItemBase implements IAnimatable {
    private final AnimationFactory factory = new AnimationFactory(this);

    public ChandlierArmorItem(ArmorMaterial material, EquipmentSlot slot, Settings settings) {
        super(material, slot, settings);
    }
    
    //盔甲动画状态机
    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.
        LivingEntity livingEntity = event.getExtraDataOfType(LivingEntity.class).get(0);

		//留空的话就默认没有动画
        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 ArmorStandEntity) {
            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 PlayerEntity) {
            PlayerEntity player = (PlayerEntity) livingEntity;

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


            //我们的盔甲只包含头盔一个
            List<Item> armorList = equipmentList.subList(5, 6);

            // Make sure the player is wearing all the armor. If they are, continue playing
            // the animation, otherwise stop
			boolean isWearingAll = armorList
					.containsAll(Arrays.asList(ItemInit.CHANDLIER));
            return isWearingAll ? PlayState.CONTINUE : PlayState.STOP;
        }
        return PlayState.STOP;
    }
    
    //将盔甲动画状态机进行注册
    @Override
    public void registerControllers(AnimationData data) {
        data.addAnimationController(new AnimationController(this,
                "controller", 20, this::predicate));
    }

    @Override
    public AnimationFactory getFactory() {
        return factory;
    }
}

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

ModelChandlier.java

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

import net.joy187.joyggd.ModMain;
import net.joy187.joyggd.items.armor.ChandlierArmorItem;
import net.minecraft.util.Identifier;
import software.bernie.geckolib3.model.AnimatedGeoModel;

public class ModelChandlier extends AnimatedGeoModel<ChandlierArmorItem> {
    //盔甲模型文件地址    
    @Override
    public Identifier getModelResource(ChandlierArmorItem object) {
        return new Identifier(ModMain.MOD_ID, "geo/chandlier.geo.json");
    }
    //盔甲材质文件地址
    @Override
    public Identifier getTextureResource(ChandlierArmorItem object) {
        return new Identifier(ModMain.MOD_ID, "textures/models/armor/chandlier_layer_1.png");
    }
    //盔甲动画文件地址
    @Override
    public Identifier getAnimationResource(ChandlierArmorItem animatable) {
        return new Identifier(ModMain.MOD_ID, "animations/chandlier.animation.json");
    }
}

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

RenderChandlier.java

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

import net.joy187.joyggd.items.armor.ChandlierArmorItem;
import net.joy187.joyggd.items.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 = "other";
		this.rightArmBone = "other";
		this.leftArmBone = "other";
		this.rightLegBone = "other";
		this.leftLegBone = "other";
		this.rightBootBone = "other";
		this.leftBootBone = "other";
    }
}

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.在items包中新建一个盔甲属性类:

CustomArmorMaterials.java

package net.joy187.joyggd.items;

import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ArmorMaterial;
import net.minecraft.item.Items;
import net.minecraft.recipe.Ingredient;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Lazy;

import java.util.function.Supplier;

public enum CustomArmorMaterials implements ArmorMaterial {
    
	ARMOR_MATERIAL_DROOL("drool", 40, new int[]{6, 10, 12, 8}, 25, SoundEvents.ITEM_ARMOR_EQUIP_CHAIN, 0.0F, 0.0F, () -> {
        return Ingredient.ofItems(Items.DIAMOND);
    }),
    ARMOR_MATERIAL_CHANDLIER("chandlier", 40, new int[]{8, 10, 12, 8}, 15, SoundEvents.ITEM_ARMOR_EQUIP_CHAIN, 2.0F, 0.5F, () -> {
        return Ingredient.ofItems(Items.DIAMOND);
    }),
    ARMOR_MATERIAL_PEACE("peace", 50, new int[]{6, 12, 8, 6}, 12, SoundEvents.ITEM_ARMOR_EQUIP_CHAIN, 4.0F, 0.2F, () -> {
        return Ingredient.ofItems(Items.DIAMOND);
    }),
    ARMOR_MATERIAL_LANTERN("lantern", 50, new int[]{8, 10, 12, 6}, 15, SoundEvents.ITEM_ARMOR_EQUIP_CHAIN, 1.0F, 0.1F, () -> {
        return Ingredient.ofItems(Items.DIAMOND);
    });
	


    private static final int[] BASE_DURABILITY = new int[]{13, 15, 16, 11};
    private final String name;
    private final int durabilityMultiplier; //耐久
    private final int[] protectionAmounts; //四个部位各有几点防御力
    private final int enchantability; //附魔能力
    private final SoundEvent equipSound;    //穿戴时的声音
    private final float toughness;  //盔甲抗性
    private final float knockbackResistance; //盔甲抗击退能力
    private final Lazy<Ingredient> repairIngredientSupplier; //盔甲用什么物品修

    private CustomArmorMaterials(String name, int durabilityMultiplier, int[] protectionAmounts,
                              int enchantability, SoundEvent equipSound, float toughness,
                              float knockbackResistance, Supplier<Ingredient> repairIngredientSupplier) {
        this.name = name;
        this.durabilityMultiplier = durabilityMultiplier;
        this.protectionAmounts = protectionAmounts;
        this.enchantability = enchantability;
        this.equipSound = equipSound;
        this.toughness = toughness;
        this.knockbackResistance = knockbackResistance;
        this.repairIngredientSupplier = new Lazy(repairIngredientSupplier);
    }

    public int getDurability(EquipmentSlot slot) {
        return BASE_DURABILITY[slot.getEntitySlotId()] * this.durabilityMultiplier;
    }

    public int getProtectionAmount(EquipmentSlot slot) {
        return this.protectionAmounts[slot.getEntitySlotId()];
    }

    public int getEnchantability() {
        return this.enchantability;
    }

    public SoundEvent getEquipSound() {
        return this.equipSound;
    }

    public Ingredient getRepairIngredient() {
        return (Ingredient)this.repairIngredientSupplier.get();
    }

    public String getName() {
        return this.name;
    }

    public float getToughness() {
        return this.toughness;
    }

    public float getKnockbackResistance() {
        return this.knockbackResistance;
    }
}

6.在ItemInit类中将我们的盔甲进行声明,使用我们上一步中所定义的盔甲属性。

ItemInit.java

    //头盔
    public static final Item CHANDLIER = registerItem("chandlier",
            new ChandlierArmorItem(CustomArmorMaterials.ARMOR_MATERIAL_CHANDLIER, EquipmentSlot.HEAD,
                    new FabricItemSettings().group(ModMain.ITEMTAB)));



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

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包,把第二步中的模型和动画文件分别放进去

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

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

2023-01-18_17.45.46.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/182189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python+django校园大学生兼职系统vue357

目 录 摘 要 I Abstracts II 目 录 III 第1章 绪论 1 1.1课题背景 1 1.2研究意义 1 1.3研究内容 2 第2章 技术介绍 1 第3章 需求分析 4 3.1需求分析概述 4 3.2可行性分析 4 3.2.1经济可行性 5 3.2.2技术可行性 5 3.3系统功能设计 …

Target 塔吉特DVS EDI 业务测试指南

Target塔吉特是美国仅次于Walmart沃尔玛的第二大巨型折扣零售百货集团&#xff0c;由于拓展了其数字化履约能力&#xff0c;使得越来越多的国内零售产品供应商和Target建立合作关系。Target要求其供应商通过EDI&#xff08;Electronic Data Interchange&#xff0c;中文名称是电…

基于蜣螂算法改进的随机森林回归算法 - 附代码

基于蜣螂算法改进的随机森林回归算法 - 附代码 文章目录基于蜣螂算法改进的随机森林回归算法 - 附代码1.数据集2.RF模型3.基于蜣螂算法优化的RF4.测试结果5.Matlab代码6.Python代码摘要&#xff1a;为了提高随机森林数据的回归预测准确率&#xff0c;对随机森林中的树木个数和最…

来看看这些电脑清理内存的方法

随着电脑使用时间的增加&#xff0c;你有没有发现电脑用得越多反应越慢&#xff1f;如果你遇到这个问题&#xff0c;可以试试这几个优化设置&#xff0c;让你的电脑速度起死回生&#xff01; 方法一&#xff1a;删除临时文件 按键盘上的Win R&#xff0c;在对话框中输入【%temp…

96. 不同的二叉搜索树

96. 不同的二叉搜索树题目算法设计&#xff1a;枚举算法设计&#xff1a;动态规划题目 传送门&#xff1a;https://leetcode.cn/problems/unique-binary-search-trees/ 算法设计&#xff1a;枚举 当 n 5&#xff0c;用 {1、2、3、4、5} BST数是多少组&#xff1f; 有 5 种情…

如何在 macOS 上安装虚拟机软件 VMware Fusion Player (个人版免费)

文章目录IntroVMware 网站注册事宜安装在 VMware Fusion 中创建虚拟机准备 iso 文件VMware Fusion 主界面Intro VMware 网站注册事宜 需要一个邮箱地址&#xff0c;先注册登陆 VMware。 然后在之后某个页面再次 register &#xff0c;就是随意填写一些字段&#xff1a;所在公…

记录晖哥程序员职业规划一次授课笔记

发现 发明 道 普通知识、特殊知识 形而上学&#xff0c;为道&#xff0c;职场规律 形而下学&#xff0c;为气&#xff0c;python、go 万物生于有&#xff0c;而有生于无&#xff01; 在职场中做无中生有的事。 利他精神 利他即利己 天予弗取反受其咎&#…

mathtype2023专门打数学符号的软件

mathtype是数学公式编辑器&#xff0c;与常见的文字处理软件及演示程序配合使用&#xff0c;能够在各种文档中加入复杂的数学公式及符号&#xff0c;可用在编辑数学的试卷、书籍、报刊、论文、幻灯演示等方面&#xff0c;mathtype2023版是编辑数学资料工具! 在这款软件中主要帮…

JavaScript基础(18)_Date对象、Math对象

Date对象 Date(日期对象)是一个构造函数,必须使用new来调用创建日期对象 1、创建一个Date对象&#xff0c;如果直接使用构造函数创建一个Date对象&#xff0c;则会封装为当前代码"执行的时间"。 var d new Date(); console.log(d); 2、创建一个指定的时间对象&am…

【C++修炼之路】14.模板进阶

每一个不曾起舞的日子都是对生命的辜负 模板进阶模板进阶一. 非类型模板参数1.1 引出场景1.2 非类型模板参数1.3 其他例子二.array类2.1 array类的介绍2.2 array的价值三.模板的特化3.1 概念3.2 函数模板的特化3.3 类模板的特化3.3.1 全特化3.3.2 偏特化四.模板分离编译4.1 什么…

人事管理系统

人才是单位的宝贵财富&#xff0c;而人事管理是人才资源的核心&#xff0c;因此快捷、高效的人事档案理系统成为单位的基本需求。 系统的主要目的是实现企业人事的信息化管理&#xff0c;主要业务是实现对员工信息的管理。 一、功能需求分析 人事管理系统主要是对人事档案管理…

MDK配色方案更改

文章目录WIN10更改护眼背景MDK软件配色方案更改设置常用关键字参考WIN10更改护眼背景 按windowsR快捷键&#xff0c;&#xff0c;打开运行&#xff0c;在弹出来的输入框中写上regedit&#xff0c;点确定或回车&#xff1a; 在打开的注册表编辑器中&#xff0c;找到目录&#…

C语言变量的作用域

所谓作用域&#xff08;Scope&#xff09;&#xff0c;就是变量的有效范围&#xff0c;就是变量可以在哪个范围以内使用。有些变量可以在所有代码文件中使用&#xff0c;有些变量只能在当前的文件中使用&#xff0c;有些变量只能在函数内部使用&#xff0c;有些变量只能在 for …

文献阅读笔记 # Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks

《Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks》 用于快速搭建NLP任务的demo的开源项目sbert的原始论文&#xff0c;star数很多&#xff0c;ACL 2019。资源: pdf | code | doc本文文献完成于 2019 年&#xff0c;因此仅代表当时的数据。相关工作&#xff…

人工智能医学影像行业背景,智能医疗的发展背景

1、人工智能未来的发展前景怎么样&#xff1f; 人工智能医疗行业主要公司&#xff1a;目前国内人工智能医疗行业代表性公司主要有&#xff1a;乐普医疗(300003)、鹰瞳科技(2251.HK)、心玮医疗(06609.HK)、美因基因(IPO中)、推想医疗科技(IPO中)等 本文核心数据&#xff1a;人…

Python爬虫(2)-Selenium控制浏览器

Selenium中提供了不少的方法来操作浏览器 Selenium控制浏览器1.打开浏览器2.打开浏览器后可以控制浏览器前进和后退就使用3.浏览器刷新4.浏览器切换网页窗口5.关闭页面和退出浏览器6.设置窗口大小7.获取窗口位置8.最大化窗口9.最小化窗口11.无窗口运行10.全屏11.屏幕截图12.元素…

opencv函数cv2.warpAffine 和 cv2.warpPerspective 的理解和复现

文章目录opencv函数cv2.warpAffine 和 cv2.warpPerspective 的理解和复现1. warpAffine 函数处理仿射变换2. warp_perspective3&#xff0c; 实验opencv函数cv2.warpAffine 和 cv2.warpPerspective 的理解和复现 1. warpAffine 函数处理仿射变换 仿射矩阵是2 * 3的矩阵。 首…

(深度学习快速入门)第三章第三节5:深度学习必备组件之欠拟合和过拟合

文章目录一&#xff1a;什么是欠拟合和过拟合二&#xff1a;正则化技术&#xff08;1&#xff09;加入正则项①&#xff1a;L1正则项②&#xff1a;L2正则项&#xff08;2&#xff09;Dropout&#xff08;暂退法&#xff09;我们训练模型的目的是为了让模型真正发现一种泛化模式…

个人流媒体服务搭建

简介 主要是个人的流媒体服务器的创建的方式分享 Centos7自建基于HLS的私人直播服务器 相关资源下载 链接&#xff1a;https://pan.baidu.com/s/1zhWFpFRy2v0_lyjA0-AfAg 提取码&#xff1a;yyds 入门操作 实现方法基于nginx和nginx的一个rtmp模块。因为epel源和nginx官…

来源于《高质量C/C++编程》的几道经典面试题

本文介绍几个非常经典的笔试题&#xff0c;原题详细解析&#xff0c;供参考题目1&#xff1a;非法访问内存泄漏题目2&#xff1a;返回栈空间地址问题--非法访问题目3&#xff1a;内存泄漏题目4&#xff1a;非法访问题目1&#xff1a;非法访问内存泄漏 void Getmemory(char* p)…