Off-screen animations play from the start once the animating entity is rendered, regardless of timing
BobMowzie opened this issue ยท 3 comments
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
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
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;
}