本次我们在Fabric模组中实现一个可用于飞行的鞘翅。
1.首先参考3D动画盔甲的教程一、二步制作盔甲的模型、动画文件。
2.模型制作完成,接下来需要制作我们的盔甲类
在items包中新建armor包 -> armor包中新建我们的套装类DressArmorItem.java
DressArmorItem.java
package net.joy187.joyggd.items.armor;
import net.fabricmc.fabric.api.entity.event.v1.FabricElytraItem;
import net.joy187.joyggd.init.ItemInit;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ArmorMaterial;
import net.minecraft.item.ElytraItem;
import net.minecraft.item.Item.Settings;
import net.minecraft.text.Text;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.manager.AnimationData;
import software.bernie.geckolib3.core.manager.AnimationFactory;
import javax.annotation.Nullable;
import java.util.List;
//要实现一下鞘翅的接口
public class DressArmorItem extends ArmorItemBase implements IAnimatable, FabricElytraItem {
private AnimationFactory factory = new AnimationFactory(this);
public DressArmorItem(ArmorMaterial material, EquipmentSlot slot, Settings settings) {
super(material, slot, settings);
}
// public DressArmorItem(Settings settings) {
// super(settings);
// }
// @Override
// public void initializeClient(java.util.function.Consumer<IClientItemExtensions> consumer) {
// consumer.accept((IClientItemExtensions) Main.CPROXY.getArmorRenderProperties());
// }
//
public static boolean isUsable(ItemStack stack) {
return stack.getDamage() < stack.getMaxDamage() - 1;
}
//右键穿戴该鞘翅
public TypedActionResult<ItemStack> use(World worldIn, PlayerEntity playerIn, Hand handIn) {
ItemStack itemstack = playerIn.getStackInHand(handIn);
EquipmentSlot equipmentslottype = LivingEntity.getPreferredEquipmentSlot(itemstack);
ItemStack itemstack1 = playerIn.getEquippedStack(EquipmentSlot.CHEST);
if (itemstack1.isEmpty()) {
playerIn.equipStack(equipmentslottype, itemstack.copy());
itemstack.setCount(0);
return TypedActionResult.success(itemstack, worldIn.isClient);
} else {
return TypedActionResult.fail(itemstack);
}
}
//用什么物品修该物品
public boolean isValidRepairItem(ItemStack toRepair, ItemStack repair) {
return repair.getItem() == Items.DIAMOND;
}
public EquipmentSlot getEquipmentSlot(ItemStack stack) {
return EquipmentSlot.CHEST;
}
@Override
public void registerControllers(AnimationData data) {
}
@Override
public AnimationFactory getFactory() {
return factory;
}
@Override
public void appendTooltip(ItemStack stack, World worldIn, List<Text> tooltip, TooltipContext flagIn) {
tooltip.add(Text.translatable("tooltip.dress"));
}
}
之后我们需要在armor包中新建model包->model包中新建我们的盔甲的模型类ModelDress:
ModelDress.java
package net.joy187.joyggd.items.armor.model;
import net.joy187.joyggd.ModMain;
import net.joy187.joyggd.items.armor.DressArmorItem;
import net.minecraft.util.Identifier;
import software.bernie.geckolib3.model.AnimatedGeoModel;
public class ModelDress extends AnimatedGeoModel<DressArmorItem> {
//鞘翅模型路径
@Override
public Identifier getModelResource(DressArmorItem object) {
return new Identifier(ModMain.MOD_ID, "geo/dress.geo.json");
}
//盔甲贴图路径
@Override
public Identifier getTextureResource(DressArmorItem object) {
return new Identifier(ModMain.MOD_ID, "textures/models/armor/dress.png");
}
//动画文件路径
@Override
public Identifier getAnimationResource(DressArmorItem animatable) {
return new Identifier(ModMain.MOD_ID, "animations/dress.animation.json");
}
}
之后我们需要在armor包中新建render包->render包中新建我们的盔甲的渲染类RenderDress:
RenderDress.java
package net.joy187.joyggd.items.armor.render;
import net.joy187.joyggd.items.armor.DressArmorItem;
import net.joy187.joyggd.items.armor.model.ModelDress;
import software.bernie.geckolib3.renderers.geo.GeoArmorRenderer;
public class RenderDress extends GeoArmorRenderer<DressArmorItem> {
//渲染盔甲穿在身上的每一个部位的效果
public RenderDress() {
super(new ModelDress());
//这里要和第二步你blockbench中建模的名称一一对应
this.headBone = "other";
this.bodyBone = "dress";
this.rightArmBone = "other";
this.leftArmBone = "other";
this.rightLegBone = "other";
this.leftLegBone = "other";
this.rightBootBone = "other";
this.leftBootBone = "other";
}
}
3.在ModClient类中将我们的盔甲渲染类进行注册:
ModClient.java
package net.joy187.joyggd;
public class ModClient implements ClientModInitializer{
@Override
public void onInitializeClient() {
//添加物品渲染
GeoArmorRenderer.registerArmorRenderer(new RenderDress(),ItemInit.DRESS);
//添加注册方法
registerModelPredicates();
}
//注册鞘翅物品模型
private void registerModelPredicates() {
FabricModelPredicateProviderRegistry.register(ItemInit.DRESS, new Identifier(ModMain.MOD_ID, "broken_elytra"), ((stack, world, entity, seed) ->
stack.getItem() == ItemInit.DRESS && DressArmorItem.isUsable(stack) ? 0.0F : 1.0F));
}
}
4.在ItemInit类中将我们的盔甲进行声明
ItemInit.java
public static final Item DRESS = registerItem("dress",
new DressArmorItem(CustomArmorMaterials.ARMOR_MATERIAL_DRESS, EquipmentSlot.CHEST,
new FabricItemSettings().group(ModMain.ITEMTAB)));