phaser
phaser copied to clipboard
[3.50-beta13] Initial glitch in Spine animation
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().
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.
I'll re-test on latest beta
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);
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.