GeckoLib

GeckoLib

146M Downloads

Block entity triggerable animation doesn't work [SOLVED]

HisokaCoding opened this issue ยท 2 comments

commented

I'd appreciate any help with it! I would like to trigger an animation when interacting with a block entity. I was able to write the following code. But something is obviously wrong, as my animation is not playing.

Block class:

public class OakCupboard extends BlockWithEntity{
    public static final DirectionProperty FACING = HorizontalFacingBlock.FACING;

    public OakCupboard(Settings settings) {
        super(settings);
        this.setDefaultState(this.stateManager.getDefaultState().with(FACING, Direction.NORTH));
    }

    @Nullable
    @Override
    public BlockState getPlacementState(ItemPlacementContext ctx) {
        return this.getDefaultState().with(FACING, ctx.getHorizontalPlayerFacing().getOpposite());
    }

    @Override
    public BlockState rotate(BlockState state, BlockRotation rotation) {
        return state.with(FACING, rotation.rotate(state.get(FACING)));
    }

    @Override
    public BlockState mirror(BlockState state, BlockMirror mirror) {
        return state.rotate(mirror.getRotation(state.get(FACING)));
    }

    @Nullable
    @Override
    public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
        return new OakCupboardEntity(pos, state);
    }

    @Override
    protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
        builder.add(FACING);
    }

    @Override
    public BlockRenderType getRenderType(BlockState state) {
        return BlockRenderType.ENTITYBLOCK_ANIMATED;
    }

    @Override
    public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
        if (state.getBlock() != newState.getBlock()) {
            BlockEntity blockEntity = world.getBlockEntity(pos);
            if (blockEntity instanceof OakCupboardEntity) {
                ItemScatterer.spawn(world, pos, (OakCupboardEntity)blockEntity);
                world.updateComparators(pos, this);
            }
            super.onStateReplaced(state, world, pos, newState, moved);
        }
    }

    @Override
    public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
        if (!world.isClient) {
            //NamedScreenHandlerFactory screenHandlerFactory = ((OakCupboardEntity) world.getBlockEntity(pos));

            //if (screenHandlerFactory != null) {
            //    player.openHandledScreen(screenHandlerFactory);
            //}

            if (hand == Hand.MAIN_HAND){
                OakCupboardEntity oakCupboard = (OakCupboardEntity) world.getBlockEntity(pos);
                oakCupboard.triggerAnim("oak_cupboard", "oak_cupboard");
            }
        }
        return ActionResult.SUCCESS;
    }
}

BlockEntity class:

public class OakCupboardEntity extends BlockEntity implements GeoBlockEntity, ExtendedScreenHandlerFactory,
        ImplementedInventory {
    private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(9, ItemStack.EMPTY);
    protected final PropertyDelegate propertyDelegate;

    private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this);

    public OakCupboardEntity(BlockPos pos, BlockState state) {
        super(ModBlocksEntities.OAK_CUPBOARD_ENTITY, pos, state);
        this.propertyDelegate = new PropertyDelegate() {
            @Override
            public int get(int index) {
                return 0;
            }

            @Override
            public void set(int index, int value) {

            }

            @Override
            public int size() {
                return 9;
            }
        };
    }

    @Override
    public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
        controllers.add(new AnimationController<>(this, "oak_cupboard",0, state -> PlayState.CONTINUE)
                .triggerableAnim("oak_cupboard",RawAnimation.begin().thenLoop("oak_cupboard")));
    }

    @Override
    public AnimatableInstanceCache getAnimatableInstanceCache() {
        return this.cache;
    }

    @Override
    public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) {
        buf.writeBlockPos(this.pos);
    }

    @Override
    public DefaultedList<ItemStack> getItems() {
        return inventory;
    }

    @Override
    public Text getDisplayName() {
        return Text.literal("Oak Cupboard");
    }

    @Nullable
    @Override
    public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
        return new OakCupboardScreenHandler(syncId, playerInventory, this, this.propertyDelegate);
    }

    @Override
    protected void writeNbt(NbtCompound nbt) {
        super.writeNbt(nbt);
        Inventories.writeNbt(nbt, inventory);
    }

    @Override
    public void readNbt(NbtCompound nbt) {
        super.readNbt(nbt);
        Inventories.readNbt(nbt, inventory);
    }
}

Animation json:

{
	"format_version": "1.8.0",
	"animations": {
		"oak_cupboard": {
			"animation_length": 1,
			"bones": {
				"door": {
					"rotation": {
						"0.0": {
							"vector": [0, 0, 0]
						},
						"0.5": {
							"vector": [0, -90, 0],
							"easing": "linear"
						},
						"1.0": {
							"vector": [0, 0, 0]
						}
					}
				}
			}
		}
	},
	"geckolib_format_version": 2
}
commented

Finally it works, thank you so much! <3

commented

That's not how you instantiate your animatable cache

Instantiate it with geckolibUtil - see the wiki