方块实体渲染器
BlockEntityRenderer 通常简称 BER,用于渲染无法用 JSON、OBJ 等静态烘焙模型表示的方块。例如,它可以动态渲染类似箱子的方块内存放的物品。使用方块实体渲染器要求方块具有 BlockEntity,即使该方块本身不需要存储数据也一样。
BER 直接实现 BlockEntityRenderer,提交需要渲染的特征:
// The generic type in the superinterface should be set to what block entity
// you are trying to render, along with its extracted render state. More on this below.
public class MyBlockEntityRenderer implements BlockEntityRenderer<MyBlockEntity, MyBlockEntityRenderState> {
public MyBlockEntityRenderer(BlockEntityRendererProvider.Context context) {
// Get whatever is necessary from the context
}
// Tell the renderer how to create a new render state.
@Override
public MyBlockEntityRenderState createRenderState() {
return new MyBlockEntityRenderState();
}
// Update the render state by copying the needed values from the passed block entity
// to the passed render state.
// The block entity and render state are the generic types passed to the renderer
@Override
public void extractRenderState(MyBlockEntity blockEntity, MyBlockEntityRenderState renderState, float partialTick, Vec3 cameraPos, @Nullable ModelFeatureRenderer.CrumblingOverlay crumblingOverlay) {
// Always call super or `BlockEntityRenderState#extractBase`
super.extractRenderState(blockEntity, renderState, partialTick, cameraPos, crumblingOverlay);
// Extract and store any additional values in the state here.
renderState.value = blockEntity.getValue();
}
// Actually submit the features of the block entity to render.
// The first parameter matches the render state's generic type.
@Override
public void submit(MyBlockEntityRenderState renderState, PoseStack poseStack, SubmitNodeCollector collector, CameraRenderState cameraState) {
// Submit using the collector here.
}
}
创建 BER 后,还需要注册它,并将其关联到对应的方块实体。可以在 EntityRenderersEvent.RegisterRenderers 中完成:
@SubscribeEvent // on the mod event bus only on the physical client
public static void registerEntityRenderers(EntityRenderersEvent.RegisterRenderers event) {
event.registerBlockEntityRenderer(
// The block entity type to register the renderer for.
MyBlockEntities.MY_BLOCK_ENTITY.get(),
// A function of BlockEntityRendererProvider.Context to BlockEntityRenderer.
MyBlockEntityRenderer::new
);
}
提示
如果 BER 不需要使用提供者上下文,也可以移除构造方法:
public class MyBlockEntityRenderer implements BlockEntityRenderer<MyBlockEntity, MyBlockEntityRenderState> { // ... } // In some event handler class @SubscribeEvent // on the mod event bus only on the physical client public static void registerEntityRenderers(EntityRenderersEvent.RegisterRenderers event) { event.registerBlockEntityRenderer(MyBlockEntities.MY_BLOCK_ENTITY.get(), // Pass the context to an empty (default) constructor call context -> new MyBlockEntityRenderer() ); }
方块实体渲染状态
如前面的示例所示,方块实体渲染状态用于从实际方块实体中提取渲染所需的值。它本质上是继承 BlockEntityRenderState 的可变数据存储对象:
public class MyBlockEntityRenderState extends BlockEntityRenderState {
public boolean value;
}
然后在 BlockEntityRenderer#extractRenderState 中,从 BlockEntity 子类提取数据,填充这些字段。
方块的物品渲染
并非所有带渲染器的方块实体都能用静态物品模型表示,因此可以创建特殊渲染器,更灵活地控制渲染过程。这通过 SpecialModelRenderer 实现。此时,既需要创建特殊模型渲染器以提交所需的特征,也要注册相应的特殊方块模型渲染器,用于直接提交方块本身而非其物品形态的场景,例如末影人搬运方块时。
更多信息请参阅客户端物品文档。
来源: NeoForged/Documentation(26.1)。中文翻译依据提交
4a680cdd4d15。