如何在Minecraft Forge 1.12.2中替换玩家模型为BlockBench自定义模型
解决Minecraft Forge 1.12.2自定义玩家模型渲染的NPE问题
问题情况
我通过BlockBench创建了自定义模型,尝试替换Minecraft Forge 1.12.2中的玩家模型渲染。切换到第三人称视角时游戏崩溃,仅显示天空盒,报错为空指针异常(NPE)。尝试使用event.getPlayer和event.getLivingEntity获取实体均未解决问题。
现有代码
自定义模型类
package com.example.examplemod;// Made with Blockbench 4.4.3 // Exported for Minecraft version 1.7 - 1.12 // Paste this class into your mod and generate all required imports import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelBox; import net.minecraft.client.model.ModelRenderer; import net.minecraft.entity.Entity; public class custom_model extends ModelBase { private final ModelRenderer bb_main; public custom_model() { textureWidth = 16; textureHeight = 16; bb_main = new ModelRenderer(this); bb_main.setRotationPoint(0.0F, 24.0F, 0.0F); bb_main.cubeList.add(new ModelBox(bb_main, 0, 0, -1.0F, -2.0F, -1.0F, 2, 2, 2, 0.0F, false)); } @Override public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) { bb_main.render(f5); } public void setRotationAngle(ModelRenderer modelRenderer, float x, float y, float z) { modelRenderer.rotateAngleX = x; modelRenderer.rotateAngleY = y; modelRenderer.rotateAngleZ = z; } }
事件注册代码
@EventHandler public void init(FMLInitializationEvent event) { MinecraftForge.EVENT_BUS.register(PlayerRenderEventClass.class); }
解决方案步骤
1. 修正事件注册方式
事件总线需要注册事件处理类的实例,而非类本身。原代码注册类的方式会导致事件处理逻辑无法正确触发,甚至引发空指针问题。修改注册代码:
@EventHandler public void init(FMLInitializationEvent event) { MinecraftForge.EVENT_BUS.register(new PlayerRenderEventClass()); }
2. 完善PlayerRenderEvent.Pre的处理逻辑
在事件处理类中,需要正确取消默认渲染、校验实体非空,并完成自定义模型的渲染:
import net.minecraft.client.renderer.entity.RenderPlayer; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.client.event.RenderPlayerEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraft.util.ResourceLocation; public class PlayerRenderEventClass { // 缓存自定义模型实例,避免每次渲染新建对象 private final custom_model customModel = new custom_model(); // 自定义模型纹理路径(替换为你的modid和纹理文件名) private final ResourceModel customTexture = new ResourceLocation("examplemod", "textures/models/custom_model.png"); @SubscribeEvent public void onPlayerRenderPre(RenderPlayerEvent.Pre event) { EntityPlayer player = event.getPlayer(); // 校验玩家实体非空,避免NPE if (player == null) return; // 取消默认玩家模型渲染 event.setCanceled(true); RenderPlayer renderer = event.getRenderer(); // 绑定自定义模型纹理 renderer.bindTexture(customTexture); // 调整模型旋转点,匹配玩家模型的原点(默认玩家模型原点在脚部) customModel.bb_main.setRotationPoint(0.0F, 24.0F - player.height, 0.0F); // 传入完整渲染参数,调用模型渲染方法 customModel.render(player, event.getPartialRenderTick(), event.getLimbSwing(), event.getLimbSwingAmount(), event.getAgeInTicks(), event.getNetHeadYaw(), event.getHeadPitch(), event.getScale()); } }
3. 调整自定义模型的适配细节
- 纹理路径:确保自定义纹理放在mod资源包的
assets/[modid]/textures/models/目录下,[modid]替换为你的mod的ID。 - 模型位置:原模型的Y轴旋转点设置为
24.0F,会导致模型偏移到玩家脚部上方,需减去玩家高度以对齐位置。 - 参数传递:必须传入完整的渲染参数(肢体摆动、头部旋转等),避免因参数缺失导致的异常。
4. NPE排查额外要点
- 确保
@SubscribeEvent注解来自net.minecraftforge.fml.common.eventhandler.SubscribeEvent,而非其他包。 - 检查自定义模型实例是否被正确初始化,避免在渲染时调用未初始化的对象。
内容的提问来源于stack exchange,提问作者MichaelHobden03
相关产品推荐
相关产品推荐

