How to sequentially play gltf animation on button click with previous animation endstate intact?

I have a gltf file with various related animations. I need to play these animations sequentially on button click.
Am able to loop through the animations but the previous animation endstate is not being maintained. What am I missing?

My code so far:

loader.load( ‘xxx.gltf’, function ( gltf ) {

  var animcount = gltf.animations.length;
  mixer = new THREE.AnimationMixer( gltf.scene );
    
  nextButton.onclick = function NextAnimation() {   
        index++;
        if(index < animcount ) {
            action1 = mixer.clipAction( gltf.animations[ index] );
            action1.clampWhenFinished = true;
            action1.timeScale = 1;
            action1.reset();
            action1.setLoop( THREE.LoopOnce )
            action1.setDuration(action1._clip.duration)
           
            if(prevAction)
                prevAction.fadeOut(0)
            
            action1.play();
            scene.add( gltf.scene );
            animate();

            mixer.addEventListener('finished', () => {
                prevAction = action1 // Save a reference to the previous action
            })
        }
    }

});

renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            renderer.gammaOutput = true;
            const controls = new OrbitControls( camera, renderer.domElement );
            document.body.appendChild(renderer.domElement);

}

@Vaishali_Valavade

try with

action.clampWhenFinished = true;

You shouldn’t create the animation actions on the fly over and over again, i’m not sure how this animation should look but if you want the previous transition into the next their weights must cross fade rather than fade out A then fade in B. You can do this manually setting the weight or use the internal functions:

Thanks for the reply. I have already used it in my code above.

@Vaishali_Valavade

appologies, overlooked that.

Sorry for my ignorance. Then would you help me as to how i should go about playing the animations interactively ( on lets say “next” button click)

Just create the actions once and store them in an array, you can use your index variable to grab it then.

scene.add( gltf.scene );
animate();

You don’t need to add the object every time again either, it won’t dublicate but just add it once outside that button click event, but especially don’t call animate there if that is your requestAnimationFrame loop.

I didn’t used the internal ones before but at here

you could try action1.crossFadeFrom( prevAction, .5) instead prevAction.fadeOut(0), last parameter is duration in seconds how long it will take to fade from A to B.

1 Like

Try it with:

Okay will give it a try.

The solutions specified are not working for me.
I am now trying a different approach. I have the gltf file with a single animation.
So now is there any way that I can play this animation from “x” seconds to “y” seconds of the entire clip duration?

I can set the starttime by action.time = {startTime}. but how can i play the animation till endTime only?

@Vaishali_Valavade

You can create subclips from the animation that run from too set frames using animationUtils

 https://threejs.org/docs/#api/en/animation/AnimationUtils