[SOLVED] How can I know animation play to the end when the loop is enabled?

Hi, I am new to PlayCanvas, it seems a great work !
I am now trying to play with the animation component and have trouble with it.
How can I know if an animation play to the end if its loop is enabled ?
What I need is something like this:

animation.on('end', function() {
    // do stuff
});

Is there any api within PlayCanvas ?
Thanks :smile:

Hi, there are no events like that on the animation component unfortunately, we do plan to improve this component in general.

For now you can get the duration of the animation from entity.animation.duration and then have your own timer to count how many seconds have passed since the animation started. You could also do a setTimeout( functionToExecuteAfterEnd, this.entity.animation.duration * 1000) although you’ll find that setTimeout is not as accurate.

1 Like

Yes, setTimeout is not accurate, its not a good way… :disappointed_relieved:

@swh @vaios

I would disable the loop of the animation, and play it manually.
Here is my implementation to listen the animation start or end:

var AnimationController = pc.createScript('animationController');

// initialize code called once per entity
AnimationController.prototype.initialize = function() {
    var animation = this.entity.animation;
    this.lastState = {
        playing: animation.playing,
        anim: animation.currAnim
    };
    
    animation.on('start', function(value) {
        console.log('animation start: ', value);
    });
    animation.on('end', function(value) {
        console.log('animation end: ', value);
        animation.play(value);
    });
};

// update code called every frame
AnimationController.prototype.update = function(dt) {
    var animation = this.entity.animation;
    var currPlaying = animation.playing;
    var lastPlaying = this.lastState.playing;
    
    if (lastPlaying === currPlaying) return;
    
    this.lastState.playing = animation.playing;
    this.lastState.anim = animation.currAnim;
        
    if (!lastPlaying && currPlaying) {
        animation.fire('start', animation.currAnim);
    } else if (lastPlaying && !currPlaying) {
        animation.fire('end', animation.currAnim);
    }
};

By this way, you don’t need to use setTimeout. :wink:

2 Likes

Wow, your implementation looks great !
I’ll try it later, thanks !

I did this in the past by keeping track of the previous frames current animation time and compare it to the current frame. If the current is lower than the previous, than it has looped.

4 Likes