-
Notifications
You must be signed in to change notification settings - Fork 0
PulseLib Blocks
Blocks in Minecraft are static by default, which means they cannot be animated on their own.
PulseLib leverages the BlockEntityRenderer system to render animated blocks. Therefore, any PulseLib-animated block must have a BlockEntity.
For instructions on creating a BlockEntity in NeoForge, see NeoForge
Important
The BlockEntity itself should implement PAnimatable, not the block.
Creating an animated PulseLib block involves five main steps:
- Creating your Blockbench Model
- Creating your Model Data
- Creating block and blockentity classes
- Disable vanilla block rendering
- Creating and register the blockentity renderer
Steps #1 and #2 will not be covered on this page, instead visit their respective links for info. This page will focus on steps #3, #4, and #5
We won’t cover basic block creation here. If you need instructions on creating a block, consult a standard block tutorial.
Once your block class exists:
- Implement
EntityBlock(or a subclass) to mark it as a blockentity. - Override
newBlockEntityand return a new instance of yourBlockEntity.
Minecraft normally uses a blockstate file to render blocks. PulseLib renders blocks differently, so we need to disable vanilla block rendering.
Override the getRenderShape method in your block class:
@Override
public RenderShape getRenderShape(BlockState state)
{
return RenderShape.ENTITYBLOCK_ANIMATED;
}This tells Minecraft to skip the default block rendering system.
Quick Summary
- Implement PAnimatable
- Override
getAnimationManagerandregisterAnimationControllers - Instantiate
PAnimationManagerviaPLibHelper.createManager(this)at the top of blockentity class - Add animation controllers in
registerAnimationControllers
- Implement
PAnimatable– base interface for all animatable objects. - Create a
PAnimationManagerinstance to store the animatable state:
private final PAnimationManager<ExampleBlockEntity> animationManager = PLibHelper.createManager(this);- Override
getAnimationManager()– return the cached manager. - Override
registerAnimationControllers()– define your animation controllers here.
Once this is done, your blockentity is ready, and you can define animations in registerAnimationControllers()
public class ExampleBlockEntity extends BlockEntity implements ArcAnimatable<ExampleBlockEntity> {
private final PAnimationManager<ExampleBlockEntity> animationManager = PLibHelper.createManager(this);
private final PRawAnimation ANIMATION = PRawAnimation.begin().
thenPlay("animation").
thenWait(20).
thenLoop("animation").
build();
public ExampleBlockEntity(BlockPos pos, BlockState state) {
super(MyBlockEntities.EXAMPLE_BLOCK_ENTITY.get(), pos, state);
}
@Override
public void registerAnimationControllers(PAnimationManager.PAnimationRegistrar<ExampleBlockEntity> registrar)
{
registrar.add(() -> animatableState ->
{
ExampleBlockEntity blockEntity = animatableState.animatable();
PAnimationController<ExampleBlockEntity> controller = animatableState.controller();
if (blockEntity.isPlayAnimation())
{
controller.play(ANIMATION);
return ControllerState.PLAY;
}
else
{
controller.stop();
return ControllerState.STOP;
}
});
}
@Override
public PAnimationManager<ExampleBlockEntity> getAnimationManager(AnimManagerKey key)
{
return this.animationManager;
}
}To render your blockentity in the world:
- Extend PBlockRenderer instead of vanilla renderers.
- Pass your PModelData and render type.
- No need to register model layers or mesh definitions.
public class ExampleBlockEntityRenderer extends PBlockRenderer<ExampleBlockEntity>
{
public ExampleBlockEntityRenderer(final EntityRendererProvider.Context context)
{
super(new DefaultBlockModelData.DefaultBlockModelDataBuilder(ResourceLocation.fromNamespaceAndPath("example_mod", "test_block")).
addTexture(ResourceLocation.fromNamespaceAndPath("example_mod", "tube_texture")).
addTexture(ResourceLocation.fromNamespaceAndPath("example_mod", "torus_texture")).
addTexture(ResourceLocation.fromNamespaceAndPath("example_mod", "pyramid_texture")).
addTexture(ResourceLocation.fromNamespaceAndPath("example_mod", "cube_texture")).
build(),
PRenderTypes.RenderTypeProvider :: trianglesTranslucent);
}
}Caution
PulseLib uses triangles for rendering instead of quads (vanilla).
This means you cannot use vanilla RenderType. Use the provided render types or create your own. Be aware, when you creating own RenderType you have to use this vertex format
Note
PulseLib uses instanced rendering for blockentity rendering. Coz Minecraft doesn't support this type of rendering by default, PulseLib rendering all blockentities in own pipeline. It's a bit later, then vanilla pipeline. So, if you want add something custom to your model, you should use preSubmit() or postSubmit() methods. You can directly add something to MultiBufferSource to use vanilla rendering or use PRenderQueue.submit() to add something to PulseLib render pipeline.
@SubscribeEvent
public static void registerRenderers(final EntityRenderersEvent.RegisterRenderers event)
{
event.registerBlockEntityRenderer(MyBlockEntities.EXAMPLE_BLOCK_ENTITY.get(), ExampleBlockEntityRenderer::new);
}This completes the setup for a fully animated PulseLib block.
Start
Basics
In depth
Specifics