You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动