[SOLVED] A smarter way to detect animation end?

 if (this.app.keyboard.wasReleased(pc.KEY_SPACE) && this.app.keyboard.isPressed(pc.KEY_W)) {
        if (this.jumpTimer <= 0) {
            this.jumpTimer = 0.5;

            setTimeout(function(){
                this.entity.rigidbody.applyImpulse(0, 700, 0);
             this.entity.children[0].animation.play('Jumping');
             setTimeout(function(){  // < ----- you can also do set interval which runs that code in that time period that you picked.
if (app.keyboard.isPressed(pc.KEY_W))
app.root.findByName('Player TPC').children[0].animation.play('Walking', 0.2);
},800);
            }.bind(this), 100);
        }
    } else if (this.app.keyboard.wasReleased(pc.KEY_SPACE) && this.app.keyboard.wasReleased(pc.KEY_W)) {
      this.entity.children[0].animation.play('Idle', 0.2);
 }
    
         else if (this.app.keyboard.isPressed(pc.KEY_SPACE) && this.app.keyboard.wasReleased(pc.KEY_W)) {
      this.entity.children[0].animation.play('Idle', 0.2);
 }



    else if (this.jumpTimer >= 0) {
        this.jumpTimer -= dt;
    }
    
    else {
        this.jumpTimer = 0;
                 //   this.entity.anim.setBoolean('justJumped', true);
    }

I’m using this to detect and predict when player is moving and jumping and to controll animations, part with setTimeout, (blend - animation duration) so it looks natural (as all animations are looped) those else ifs preditcs if other combinations are not pressed and limits it since players do only jump when moving forward (W pressed space released)

I’m also using PlayerAnimationHandler

PlayerAnimationHandler.prototype.checkButtons = function () {
    var app = this.app;

    var w = app.keyboard.isPressed(pc.KEY_W) || app.keyboard.isPressed(pc.KEY_UP);
    var a = app.keyboard.isPressed(pc.KEY_A) || app.keyboard.isPressed(pc.KEY_LEFT);
    var s = app.keyboard.isPressed(pc.KEY_S) || app.keyboard.isPressed(pc.KEY_DOWN);
    var d = app.keyboard.isPressed(pc.KEY_D) || app.keyboard.isPressed(pc.KEY_RIGHT);

    if (w && !s) {
        if (a && !d) {
            this.direction = 'Walking'; // Run Forward Left
        } else if (d && !a) {
            this.direction = 'Walking'; //Run Forward Right
        } else {
            this.direction = 'Walking'; // Run Forward
        }
    } else if (s && !w) {
        if (a && !d) {
            this.direction = 'WalkBack'; // Run Backward Left
        } else if (d && !a) {
            this.direction = 'WalkBack'; // Run Backward Right
        } else {
            this.direction = 'WalkBack'; // Run Backward
        }
    } else if (a && !d) {
        this.direction = 'WalkLeft'; // Run Left
    } else if (d && !a) {
        this.direction = 'WalkRight'; // Run Right
    } else {
        this.direction = 'Idle'; // Idle
    }

};

I’ve tried this method [SOLVED] Third Person Jump and Play Animation - #4 by Albertos
but it lacks some key features as preventing multiple jumps + animation only plays on isPressed not the full anim, and wasReleased totally breaks the anims

Any ideas? heard setTimeout is not good to use

Based on the code form the posts you can use the jump timer to fix these problems. It will look something like below.

    } else if (space && this.jumpTimer === 0) {
        this.entity.animation.loop = false;
        this.direction = 'Jump';
    } else if (this.jumpTimer === 0) {
        this.entity.animation.loop = true;
        this.direction = 'Idle';
    }

What are those timeouts for? Can’t you use the jump timer for this?

Since I started jumping animation, I’m checking if player is still moving e.g pressing w key, if so I set the amimation back to walking, simulating end of jumping

I’d rather use animation handler method, but like i said I want to use ‘wasReleased’ as my goal is to play full animation, isPressed would play just a few ms of that animation, and looping makes animations stuck lets say we are going forward and jumping, forward would fail after jump

So you want to walk in the air?

I don’t see why. You start an animation and if you don’t change or stop it, it keeps playing. You just need to make sure every rule is called on the right time, with using statements.

Not sure what loopings has to do with it. Forward will start playing after jump I guess?

Indeed it would, if you’re not holding W whole time
I’ll make a video later on

Ah, why you didn’t say that earlier? In that case you need to change the order of my example. First check if the player want to jump or is jumping.

PlayerAnimationHandler.prototype.update = function (dt) {
    if (this.cameraScript.LTouch){
        var tempDirection = this.direction;

        this.checkTouch();

        if (tempDirection !== this.direction) {
            this.setDirection(this.direction);
        }
    }

    if (justJumped == true)
      if (this.jumpTimer <= 0) {
            this.jumpTimer = 1;
justJumped = false;
console.log('You can jump again!');
    } else if (this.jumpTimer >= 0) {
        this.jumpTimer -= dt;
    }
    else {
        this.jumpTimer = 0;  
    }
};


PlayerAnimationHandler.prototype.checkButtons = function () {
    var app = this.app;

    var w = app.keyboard.isPressed(pc.KEY_W);
    var a = app.keyboard.isPressed(pc.KEY_A);
    var s = app.keyboard.isPressed(pc.KEY_S);
    var d = app.keyboard.isPressed(pc.KEY_D);
    var space = app.keyboard.isPressed(pc.KEY_SPACE);

    if (w && !s) {
        if (a && !d) {
            this.direction = 'Walking'; // Run Forward Left
        } else if (d && !a) {
            this.direction = 'Walking'; //Run Forward Right
                } else if (w && space && justJumped == false) {
            justJumped = true;
            console.log('Jumped');
            this.direction = 'Jumping'; //Run Forward Right    
        } else {
            this.direction = 'Walking'; // Run Forward
        }
    } else if (s && !w) {
        if (a && !d) {
            this.direction = 'WalkBack'; // Run Backward Left
        } else if (d && !a) {
            this.direction = 'WalkBack'; // Run Backward Right
        } else {
            this.direction = 'WalkBack'; // Run Backward
        }
    } else if (a && !d) {
        this.direction = 'WalkLeft'; // Run Left
    } else if (d && !a) {
        this.direction = 'WalkRight'; // Run Right
         } else if (space && justJumped == false) {
            justJumped = true;
            console.log('Jumped');
         this.direction = 'Jumping';
    } else {
        this.direction = 'Idle'; // Idle
    }

};

Glad I’m avoiding setTimeout’s now
This is somewhat working now, with a little tweaks I will make it perfect, thanks Albertos, I hope I will explain things better in near future (Something hard to code is coming so I will make a new post)

Did you also solve this with the above code? I don’t think so.

I did, tested and everything works as expected
We can mark this as solved

1 Like