Start Animation on Random Frame

Hi,

I’m trying to set the starting frame of an animation to any random point in the duration of the animation but it seems I can’t access either the duration of the animation or the current time. Is this a bug, or am I not accessing the values properly?

The documentation says the properties I’m looking for are duration and currentTime but when I try to access them I get an error saying it’s undefined. If I print the entire animation component to the console though, I can see all the values I’m looking to access.

this.object.animation.play(this.idleClip.name);
console.log(this.object.animation);                        //Prints the entire animation component (I can see the values I need)
console.log(this.object.animation.duration);               //Gives an 'undefined' error

The idle animation plays just fine but every instance of the object plays the same frame at the same time. I’d like to set the animation’s currentTime based on a random number between 0 and the duration of the animation.

Any suggestions would be appreciated. Thank you!

Hi @RipcordDev,

I’ve modified the animation blending tutorial to start the punch on a random a frame each time you press P. I attach the code below, note for this to work animation blending should be set to 0.0.

Otherwise anim blending will override any currentTime property you set. Otherwise you need to set your random frame after blending has finished.

var AnimationBlending = pc.createScript('animationBlending');

AnimationBlending.states = {
    idle: { 
        animation: 'male.json' 
    },
    punch: { 
        animation: 'male_uppercut_jab.json' 
    }
};

// initialize code called once per entity
AnimationBlending.prototype.initialize = function() {
    this.blendTime = 0.0;

    this.setState('idle');

    this.app.keyboard.on(pc.EVENT_KEYDOWN, this.keyDown, this);
    this.app.keyboard.on(pc.EVENT_KEYUP, this.keyUp, this);
};

AnimationBlending.prototype.setState = function (state) {
    var states = AnimationBlending.states;
    
    this.state = state;
    // Set the current animation, taking 0.2 seconds to blend from
    // the current animation state to the start of the target animation.
    this.entity.animation.play(states[state].animation, this.blendTime);
    
    if( state === 'punch' ){
        var max = this.entity.animation.duration;
        var min = 0.0;
        
        this.entity.animation.currentTime = Math.floor(Math.random() * (max - min + 1) + min);
    }
};

AnimationBlending.prototype.keyDown = function (e) {
    if ((e.key === pc.KEY_P) && (this.state !== 'punch')) {
        this.setState('punch');
    }
};

AnimationBlending.prototype.keyUp = function (e) {
    if ((e.key === pc.KEY_P) && (this.state === 'punch')) {
        this.setState('idle');
    }
};

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

1 Like

Hey @Leonidas thank you for this. I finally had some time to come back to this project and test a few things out.

Testing this out in a new empty project worked as expected (getting the animation’s duration value and setting the currentTime). There must have been something else in the original project that was interfering with things.

I’ve learned what I needed to learn though, so if I ever need to go back to that old project at least I know it’s not the animation code that’s causing problems. Thank you!

1 Like