Last active
September 11, 2024 02:25
-
-
Save rtpHarry/2d41811d04825935039dfc075116d0ad to your computer and use it in GitHub Desktop.
Three.js - play an AnimationAction in reverse. There are a bunch of threads saying this isn't possible but I found a way so I wanted to post it online in a place that people will hopefully stumble upon it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The class itself is based on the animation helper class in | |
// https://github.com/paulmg/ThreeJS-Webpack-ES6-Boilerplate | |
// but I have changed almost everything except for the class name and the update function. | |
import * as THREE from 'three'; | |
export default class Animation { | |
constructor(scene, animations) { | |
this.scene = scene; | |
this.animations = animations; | |
this.mixer = new THREE.AnimationMixer(this.scene); | |
} | |
playClipByIndex(index) { | |
// (mixer.clipAction() will also take a name string if that works better for your setup) | |
this.action = this.mixer.clipAction(this.animations[index]); | |
this.action.reset() | |
this.action.timeScale = 1; | |
this.action.setLoop(THREE.LoopOnce); | |
this.action.clampWhenFinished = true; | |
this.action.play(); | |
} | |
// assumes that the mixer has already played | |
playClipReverseByIndex(index) { | |
// (mixer.clipAction() will also take a name string if that works better for your setup) | |
this.action = this.mixer.clipAction(this.animations[index]); | |
this.action.paused = false; | |
this.action.timeScale = -1; | |
this.action.setLoop(THREE.LoopOnce); | |
this.action.play(); | |
} | |
// will force the mixer to play in reverse no matter what | |
playClipReverseByIndex_Forced(index) { | |
this.action = this.mixer.clipAction(this.animations[index]); | |
if(this.action.time === 0) { | |
this.action.time = this.action.getClip().duration; | |
} | |
this.action.paused = false; | |
this.action.setLoop(THREE.LoopOnce); | |
this.action.timeScale = -1; | |
this.action.play(); | |
} | |
// Call update in loop | |
update(delta) { | |
if(this.mixer) { | |
this.mixer.update(delta); | |
} | |
} | |
} |
It's been a while since I used this code, but the purpose of it was to only do it once. There are line in your code that say actionMorph.setLoop(THREE.LoopOnce);
which seems like they are going to cause you issues. It also looks like you are using something different with animMorph
coming from clipAction
not being a straight mixer like my code example. I'm afraid I can't be much help from looking at your code. My skills in this area have faded out.
Just came across wanting to do the same @ametthey, it looks like you just need to call action.reset()
before playing the animation on mouse down and it should work as expected.
playClipReverseByIndex_Forced
works for me :) thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey Harry, thanks a lot for sharing this code. I have been trying to create an animation on a click event, and on another click doing a reverse animation. It's working when I do the animation/animation reverse once but not like everytime I want, you have an idea ??
I'm taking the leap to share my code
This is my GLTF object with morph animation.
And this is my code when I trigger the animation
I really don't understand why it's only doing the animation once !!!