Skip to content

Entity Render Layers

PEntityRenderLayer renders an additional PulseLib model on top of a PEntityRenderer.

Layers are useful for armor pieces, equipment, accessories, conditional attachments, or model variants.

Layer class

public class RobotChestLayer extends PEntityRenderLayer<RobotEntity, PEntityRenderState.LivingImpl<RobotEntity>> {
    public RobotChestLayer() {
        super(new DefaultEntityLayerModelData.DefaultEntityLayerModelDataBuilder(
                        MyEntities.ROBOT.getId(),
                        Identifier.fromNamespaceAndPath("examplemod", "armor"))
                        .build(),
                PRenderTypes.RenderTypeProvider::trianglesSolid);
    }

    @Override
    public boolean shouldRender(PEntityRenderState.LivingImpl<RobotEntity> renderState) {
        return renderState.getAnimatable().hasChestPlate();
    }
}

Add layer to renderer

public class RobotRenderer extends PEntityRenderer<RobotEntity, PEntityRenderState.LivingImpl<RobotEntity>> {
    public RobotRenderer(EntityRendererProvider.Context context) {
        super(context, ROBOT_MODEL_DATA, PRenderTypes.RenderTypeProvider::trianglesSolid);

        addRenderLayer("body",
                new RobotChestLayer()
                        .bindBone("armor_body", "body")
                        .bindBone("armor_head", "head"));
    }
}

addRenderLayer(anchorBoneName, layer) attaches the layer at the named bone on the base model.

Bone bindings

Layer bone bindings copy base entity bone poses into layer bones:

new RobotChestLayer()
        .bindBone("layer_right_arm", "right_arm")
        .bindMatchingBone("head")
        .bindMatchingBones("left_leg", "right_leg");

Use this when the layer model should follow animated limbs from the base model.

Transform and appearance hooks

RobotChestLayer layer = new RobotChestLayer();
layer.setOffset(new Vector3f(0.0f, 0.05f, 0.0f));
layer.setRotation(new Quaternionf().rotationXYZ(0, 0, 0));
layer.setScale(new Vector3f(1.05f, 1.05f, 1.05f));

Override appearance hooks:

@Override
public int getColor(PEntityRenderState.LivingImpl<RobotEntity> renderState,
                    PBakedBone bone,
                    PBakedMesh mesh,
                    int packedColor) {
    return renderState.getAnimatable().isPowered() ? 0xFF80FFFF : packedColor;
}

@Override
public int getPackedLight(PEntityRenderState.LivingImpl<RobotEntity> renderState, int packedLight) {
    return renderState.getAnimatable().isPowered() ? LightTexture.FULL_BRIGHT : packedLight;
}

Classes used: