Minecraft 1.7.10自定义盔甲渲染:取消默认盔甲显示问题
解决Minecraft自定义盔甲与默认盔甲重复渲染的问题
我最近在开发Minecraft模组时遇到了一个头疼的问题:想要替换游戏默认的盔甲渲染效果,但默认的“大型”盔甲模型始终会显示出来,导致两种盔甲叠加渲染的情况。
最初的代码实现
我一开始写的盔甲类代码是这样的:
package com.bnhc.items; import com.bnhc.client.render.CArmour; import com.bnhc.main.Main; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.model.ModelBiped; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; public class CCloth extends ItemArmor { public CCloth(ArmorMaterial material, int armorType, int armorIndex) { super(material, armorType, armorIndex); } public String getArmorTexture(ItemStack itemstack, Entity entity, int slot, String layer) { if(((itemstack.getItem() == MIte.ua_sports_layer_1) || (itemstack.getItem() == MIte.ua_sports_layer_1))){ return "bnhc:textures/armour/uasports_layer_1.png"; } return null; } CArmour armorModel = new CArmour(0.0F); @Override @SideOnly(Side.CLIENT) public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) { if (itemStack != null) { if (itemStack.getItem() instanceof CCloth) { int type = ((ItemArmor)itemStack.getItem()).armorType; if (type == 1) { armorModel = Main.proxy.getArmorModel(0); } else { armorModel = Main.proxy.getArmorModel(1); } } if (armorModel != null) { armorModel.isSneak = entityLiving.isSneaking(); armorModel.isRiding = entityLiving.isRiding(); armorModel.isChild = entityLiving.isChild(); armorModel.heldItemRight = entityLiving.getEquipmentInSlot(0) != null ? 1 :0; if(entityLiving instanceof EntityPlayer) { armorModel.aimedBow =((EntityPlayer)entityLiving).getItemInUseDuration() > 2; } return armorModel; } } return armorModel; } }
对应的客户端代理代码:
@Override public CArmour getArmorModel(int id) { return customArmour; }
问题排查与解决
后来我终于找到问题根源:使用ModelBiped时默认已经会触发渲染逻辑,再加上客户端代理的额外模型获取设置,直接导致了重复渲染。只需要移除客户端代理相关的内容,同时调整盔甲模型的部位显示逻辑,就能彻底解决这个问题。
修改后的修复版本代码
package com.bnhc.items; import com.bnhc.CreativeTabs.CTBS; import com.bnhc.main.Ref; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.model.ModelBiped; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; public class CCloth extends ItemArmor { public CCloth(ArmorMaterial armorMaterial, int renderindex, int armortype,String name) { super(armorMaterial, renderindex, armortype); } public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type) { if(stack.getItem() == MIte.ua_sports_chest) { return Ref.MODID+ ":textures/armour/uasports_layer_1.png"; }else if(stack.getItem() == MIte.ua_sports_leggs){ return Ref.MODID+ ":textures/armour/uasports_layer_2.png"; }else { return null; } } ModelBiped armorModel = new ModelBiped(); @Override @SideOnly(Side.CLIENT) public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) { if(itemStack != null){ if(armorModel != null){ armorModel.bipedRightLeg.showModel = armorSlot == 2; armorModel.bipedLeftLeg.showModel = armorSlot == 2; armorModel.bipedBody.showModel = armorSlot == 1; armorModel.bipedRightArm.showModel = armorSlot == 1; armorModel.bipedLeftArm.showModel = armorSlot == 1; armorModel.bipedHead.showModel = armorSlot == 0; armorModel.isSneak = entityLiving.isSneaking(); armorModel.isRiding = entityLiving.isRiding(); armorModel.isChild = entityLiving.isChild(); armorModel.heldItemRight = entityLiving.getEquipmentInSlot(0) != null ? 1 :0; if(entityLiving instanceof EntityPlayer){ armorModel.aimedBow =((EntityPlayer)entityLiving).getItemInUseDuration() > 2; } return armorModel; } } return armorModel; } }
关键修复点
- 移除了客户端代理中获取盔甲模型的逻辑,因为
@SideOnly(Side.CLIENT)注解已经足够保证代码只在客户端执行,不需要额外通过代理获取模型 - 新增了盔甲模型各部位的显示判断,根据不同的盔甲槽位(armorSlot)精准控制对应身体部位模型是否显示,彻底避免了默认模型的全量渲染
内容的提问来源于stack exchange,提问作者Oscarita25




