GeckoLib

GeckoLib

146M Downloads

Off-screen animations play from the start once the animating entity is rendered, regardless of timing

BobMowzie opened this issue ยท 3 comments

commented

If an animation starts while a mob is not rendered, the animation will play from the beginning. Instead, the animation should play as though it had started already, taking into account the time spent not rendered. If the animation's full duration had passed while not rendered, the animation should not play at all.

This gremlin example plays an interact animation when given an item. However, if the player looks away before the animation begins, the animation won't play until the player looks back at the Gremlin. Not very consequential for an interact animation, but for an attack animation that players need to dodge or block with correct timing, this would make a big difference.

Minecraft_Forge__1.20.1_-_Singleplayer_2024-05-06_23-26-37.mp4
commented

This involves a fundamental change in the signalling of Geckolib's animations, which poses problems

It's on the cards for eventually, but it's not an easy proble mto solve gracefully

in the meantime, if you have mobs this is critical on, I'd recommend setting noCulling = true on that mob so that it doesn't cull

commented

Understood. Thanks for holding on to this.
If it helps at all, I was able to solve it specifically for Mowzie's Mobs needs by using a combination of this new playAnimation function and a rewritten adjustTick.
But I'm fairly certain this only works for specifically how I use Geckolib. And I have no idea why it works or how I arrived at this solution.

    public void playAnimation(T animatable, RawAnimation animation) {
        forceAnimationReset();
        setAnimation(animation);
        currentAnimation = this.animationQueue.poll();
        isJustStarting = true;
        adjustTick(animatable.getTick(animatable) + Minecraft.getInstance().getPartialTick());
        transitionLength = 0;
    }

    @Override
    protected double adjustTick(double tick) {
        if (this.shouldResetTick) {
            if (getAnimationState() == State.TRANSITIONING) {
                this.tickOffset = tick;
            }
            else if (getAnimationState() != State.STOPPED) {
                this.tickOffset += transitionLength;
            }
            this.shouldResetTick = false;
        }

        double adjustedTick = this.animationSpeedModifier.apply(this.animatable) * Math.max(tick - this.tickOffset, 0) + timingOffset;
        if (this.currentAnimation != null && this.currentAnimation.loopType() == Animation.LoopType.LOOP) adjustedTick = adjustedTick % this.currentAnimation.animation().length();
        if (adjustedTick == timingOffset) isJustStarting = true;
        return adjustedTick;
    }
commented

Try doing this via the death ticks query in 4.6+