Spine play new animation after a specific animation has finished

I want to play an animation (a looping idle- Wave_02) after my initial animation (fade_in) has finished. It looks like the SPine project example on playcanvas is ols redundant code. I tried the following (insied the update loop) but it doesn’t do anything :

this.entity.spine.state.onComplete = function (track, count) 
    {
        if (this.entity.spine.state.animation.name == "Fade_In") 
        {
            this.entity.spine.state.setAnimation(0, "Wave_02", true);
        }
    };

Can anyone help with this?
Thanks

Spine API documentation would be a good starting point to find the functions you might need to call.
http://en.esotericsoftware.com/spine-api-reference

Yeah, I checked this but a lot of it makes no sense and its all very long winded. I just cant figure out how to listen for the on complete event in Playcanvas.

Example:

https://playcanvas.com/editor/scene/1134104

var PlayAnim = pc.createScript('playAnim');

// initialize code called once per entity
PlayAnim.prototype.initialize = function() {
    this.entity.spine.state.addListener({
        complete: function (entry) { console.log('complete'); },
        dispose: function (entry) { console.log('dispose'); },
        end: function (entry) { console.log('end'); }, 
        event: function (entry) { console.log('event'); }, 
        interrupt: function (entry) { console.log('interrupt'); }, 
        start: function (entry) { console.log('start'); } 
    });  
    var trackEntry = this.entity.spine.state.setAnimation(0, "portal", true);
};

// update code called every frame
PlayAnim.prototype.update = function(dt) {
    
};
1 Like

Thanks but I still cant get this working. Nothing happens with your code (my full code below). Admittedly I am very new to Playcanvas but this all seems very convoluted just to be able to trigger a single animation.

I don’t really know what is going on here and I cant even debug the thing because my PC doesn’t detect my phone when attached via USB (debug over USB is on)

:frowning:

PlayAnim.prototype.initialize = function() {

this.entity.spine.state.addListener({
    complete: function (entry) { console.log('complete'); },
    dispose: function (entry) { console.log('dispose'); },
    end: function (entry) { console.log('end'); }, 
    event: function (entry) { console.log('event'); }, 
    interrupt: function (entry) { console.log('interrupt'); }, 
    start: function (entry) { console.log('start'); } 
});  

}

PlayAnim.prototype.update = function(dt) {

//when fade in animation is complete play Wave 2 animation

this.entity.spine.state.complete = function (track, count) 
{

    if (this.entity.spine.animation.name == "Fade_In") 
    {
       
        this.entity.spine.state.setAnimation(0, "Wave_02", true);
    }
};

};

can you debug on PC instead of on the phone? That’s what I do in majority of cases.

That’s what I’ve been trying, but my PC never detect my device at chrome://inspect/#devices :frowning:

I mean do not use device at all … simply point run your playcanvas project in the browser on the pc, and debug it right there in the same window it’s running in.

For example, open this on the Chrome on the PC: http://playcanvas.github.io/#graphics/lights.html
And then in Chrome go to Settings menu (3 dots on the top right), and select More Tools -> Developer Tools. And you can debug the application right there.

I would, but I’m working on an AR project it seems that I have to use a real device rather than say the the PC webcam.

I don’t know much at this but I have Web XR emulator plugin in chrome that lets me debug some WebXR based projects there … would something like this work for you? @yaustar might know more.

Cheers, but regardless of the debug tools I’d really like to know how to get this animation working. I’ve been trying to use PLaycanvas for my project but so far its taken days and days to get nowhere. I am at the point of giving up and cancelling the whole thing with the client :frowning:

Coming from Unity, I had hoped that simple things like triggering an animation, fading in an animation, changing the colour of a model to match a pixel on screen would take a few hours to implement, but so far I’ve spend days on each of these tasks and have got absolutely nowhere. I really can’t tell you how frustrated I am by the whole thing. :frowning:

I realise that most of the issues are becasue of the Spine plugin/lack of help with that.

I believe Grimmy is using 8th Wall so it needs to ran on device at the moment. @Grimmy you may need to install Android USB drivers to debug over USB. Otherwise you can try vConsole and remote.js in the meantime or make the project work without 8th Wall if need be.

This is mostly because Spine is an external integration and some of the logic is going to be using the Spine runtime directly unfortunately and therefore understanding how their API works.

This looks like what you are looking for:

PlayAnim.prototype.initialize = function() {
    var self = this;
    this.entity.spine.state.addListener({
        complete: function (entry) { 
            if (self.entity.spine.animation.name == "Fade_In") {
                self.entity.spine.state.setAnimation(0, "Wave_02", true);
            }
        }
    });  
    var trackEntry = this.entity.spine.state.setAnimation(0, "portal", true);
};
1 Like

Thanks. With that code I get

‘Cannot read property ‘name’ of undefined’

at the point the animation is supposed to change…?

Ah sorry, I assumed that code worked as I copied it from yours :sweat_smile: You have to bear with me as I’m learning as I go here :grimacing:

PlayAnim.prototype.initialize = function() {
   var self = this;
   this.entity.spine.state.addListener({
       complete: function (entry) { 
           if (entry.animation.name == "Fade_In") {
               self.entity.spine.state.setAnimation(0, "Wave_02", true);
           }
       }
   });  
   var trackEntry = this.entity.spine.state.setAnimation(0, "portal", true);
};

Just elaborate a bit: this.entity.spine is our PlayCanvas component as defined here: https://github.com/playcanvas/playcanvas-spine/blob/master/src/component/spine-component.js

The state property on this.entity.spine.state is the AnimationState from here: http://en.esotericsoftware.com/spine-api-reference#AnimationState

This allows us to use the Spine API directly so as using addListener http://en.esotericsoftware.com/spine-api-reference#AnimationState-addListener

Okay great, its working. Thanks for the detailed help.

There is a problem that there seems to be a gap (the whole spine model disappears) of one frame or something as the animation changes from fade_in to Wave_02.

Is that fixable?

Looking at the docs, it sounds like playing an animation from the callback is a frame late: http://en.esotericsoftware.com/spine-api-reference#AnimationStateListener-complete

You can probably get around this by looping the first animation (complete is still called)

(could you add a video on what this looks like please as that will help to see if I’m looking at the same thing)

It sounds like using http://en.esotericsoftware.com/spine-api-reference#AnimationState-addAnimation2 is what you really want but I haven’t been able to get this working yet myself with the demo assets.

Edit: scratch that, I’ve got it working: https://playcanvas.com/editor/scene/1134249

1 Like

Here is a video: https://www.dropbox.com/s/s1xbdtkaux5pgwd/SVID_20210419_150721_1.mp4?dl=0

I have the first anim looping but still get the glitch.

Ah I see. So just doing those two lines and nothing else everything works without a glitch…

The fade in plays once then switches smoothly to the looping anim.

this.entity.spine.state.setAnimation(0, "Fade_In", false);
this.entity.spine.state.addAnimation(0, "Wave_02", true, 0);
1 Like

I still have a small issue with this in that when my AR image target loses focus and then I focus it again, there is a single frame of the previous animation that plays before the initial fade in animation begins again. See here:
https://www.dropbox.com/s/l0k1ugvzuw20dwa/SVID_20210420_113918_1.mp4?dl=0

I tried doing this when my image target regains focus but it doesnt seem to do anything:
this.entity.spine.state.setEmptyAnimations(0);
this.entity.spine.state.update(0);

I also tried doing the same thing when it loses focus but I cant seem to shake this little glitch.
ANy ideas?

A couple of things I would try:

  • Setting the animation but don’t enable/show the entity till the next X frames (e.g moving the sprite to behind the camera and then moving it back a frame or two later)
  • Try setting playing the animation on the next frame after the focus is regained by the AR

I can’t reproduce the issue from disabling the entity and renabling with a new animation: https://playcanvas.com/editor/scene/1134104

Press 2 to disable and then 1 to re-enable. This makes me think that the second option would work (enabling and playing the animation on the frame after the focus gained event)