phaser icon indicating copy to clipboard operation
phaser copied to clipboard

[3.50-beta13] Initial glitch in Spine animation

Open spayton opened this issue 4 years ago • 3 comments

Version

  • Phaser Version: 3.50-beta12/13 (and probably a lot of previous versions)
  • OS/Browser: Win10 Chrome

Description

When a hidden spine is made visible and an animation started, the first frame of animation seen is not the expected first frame of animation.

This glitch depends on when the spine was made visible and animated, it will be a problem if this is triggered after the normal spine update. Triggering from a tween completion callback is one such situation where the glitch will show itself. The glitch is that the spine momentarily appears in its last state at the start of it's animation.

If the spine is made visible and animated, in a tween completion callback, the spine will miss its preUpdate() before its render() is called, critically this misses the spine.state.apply(skeleton) resulting in the glitch on the first render.

However, if the spine is made visible and animated on a pointerup event, then the glitch doesn't occur because the trigger occured outside the normal step processing, thus the normal step processing subsequently occurs from the start, ie step -> sceneManager.update -> etc, thus the spine.preUpdate() gets called before the first render().

spayton avatar Dec 11 '20 00:12 spayton

I know this issue is pretty old now, but if it still happens in Beta 21 then please post a simple test case here so I can look at it for the 3.60 release.

photonstorm avatar Mar 31 '23 15:03 photonstorm

I'll re-test on latest beta

spayton avatar Apr 02 '23 10:04 spayton

yes, it still does it, here's an example.

open labs example with 3.60beta22: https://labs.phaser.io/edit.html?src=src\3.60\spine3\basic%20spineboy.js&v=3.60.0-beta.22

then replace the code with this code below

the shrinking logo is a visual indicator of when the spines will appear. The boy on the left will appear and animate normally, the one on the right will appear but the animation will initially glitch.

Both boys are created and started equally, the only difference is the trigger that makes them appear and start animating.

The left boy (good) is started in a setTimout() callback, the right boy (bad) is started in a tween callback.

Possibly it needs some sort of 'needsUpdating' dirty flag to detect that its trying to render but has missed its update.

class Example extends Phaser.Scene
{
    constructor ()
    {
        super({ pack: { files: [
                    { type: 'scenePlugin', key: 'SpinePlugin', url: 'plugins/3.8.95/SpinePluginDebug.js', sceneKey: 'spine' }
                ] } });
    }

    preload ()
    {
        this.load.image('logo', 'assets/sprites/phaser.png');
        this.load.setPath('assets/spine/3.8/demos/');
        this.load.spine('set1', 'demos.json', [ 'atlas1.atlas' ], true);
    }

    create ()
    {
        const logo = this.add.image(400, 50, 'logo');
        const leftBoy = this.add.spine(200, 500, 'set1.spineboy').setScale(0.5).setVisible(false);
        const rightBoy = this.add.spine(600, 500, 'set1.spineboy').setScale(0.5).setVisible(false);

        setTimeout( ()=>this.startAnimation(leftBoy), 1000 );

        this.tweens.add({
            targets: logo, scale:0, duration:1000, 
            onComplete: ()=>this.startAnimation(rightBoy)
        })
    }

    startAnimation (boy) {
        boy.play('idle',true);
        boy.visible = true;
    }
}

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    scene: Example
};

const game = new Phaser.Game(config);

spayton avatar Apr 05 '23 14:04 spayton

Thank you for submitting this issue. We have fixed this and the fix has been pushed to the master branch. It will be part of the next release. If you get time to build and test it for yourself we would appreciate that. Note: Only fixed for Spine 4.1 plugin.

photonstorm avatar Feb 01 '24 12:02 photonstorm