Switching between animations from different fbx files applied on glb

I have here a model.glb, and two different fbx animations without skin. I want to switch between the animations smoothly; here is a working prototype with abrupt animation switching:

function Model(props) {
  const { nodes, scene } = useGLTF(props.url);
  const wavingAction = useFBX("Waving.fbx");
  const wavingAnimation = wavingAction.animations;
  const talkingAction = useFBX("Talking.fbx");
  const talkingAnimation = talkingAction.animations;

  const mixer = useRef(new AnimationMixer());

  useFrame((state, delta) => mixer.current.update(delta));

  useEffect(() => {
    mixer.current.clipAction(talkingAnimation[0], scene).play();
  }, [])

  useEffect(() => {
    const unsubscribe = subscribe(proxy, () => {
      if (proxy.isTalking) {
        mixer.current.clipAction(talkingAnimation[0], scene).play();
        mixer.current.clipAction(wavingAnimation[0], scene).stop();
      } else {
        mixer.current.clipAction(wavingAnimation[0], scene).play();
        mixer.current.clipAction(talkingAnimation[0], scene).stop();
    return () => {
  }, [proxy]); // Make sure to pass the correct dependencies

  return <primitive {...props} object={scene} />;

So I replaced the state conditions like this:

      if (proxy.isTalking) {
        mixer.current.clipAction(talkingAnimation[0], scene).fadeIn(0.5).play();
        mixer.current.clipAction(wavingAnimation[0], scene).fadeOut(0.5).stop();
      } else {
        mixer.current.clipAction(wavingAnimation[0], scene).fadeIn(0.5).play();
        mixer.current.clipAction(talkingAnimation[0], scene).fadeOut(0.5).stop();

But now it is animating once and then bouncing back to the reset (T-pose) form.

there is also the possiblity of crossFadeTo(action); but I think I need to rearange my code structure and use the mixer differently.

three fiber, drei is welcome; but I also appriciate basic three.js.

Whether I’m using r3f or vanilla, the general sequence I use is,

  • fadeOut the old action,
  • reset, fadeIn and play the new action.

E.g., going from idle to walking


R3F example : Obstacle Course
Vanilla/TypeScript : Kick Boxing

In react you could also use this basic pattern (untested, use it as a guide)

  const [action, setAction] = useState()

  useEffect(() => {
    action && action.reset().fadeIn(0.1).play()
    return () => {
      action && action.fadeOut(0.1)
  }, [action])

then some where else in your code call

Also. if you open your FBX animations in blender, you can then export them as glB and the file sizes will be much smaller.

1 Like

Don’t you need an animationmixer to handle the transition between the animations? I updated the component similar to your code; what I noticed is it is always going to the T-pose first and then from there transition to the next animation - shouldn’t it just fade into the next animation where ever the bones are at the moment when I say fadeout? - or does fadeout means: go to reset pose?

      if (proxy.isTalking) {
          // wavingClipAction.crossFadeTo(talkingClipAction, 1, true); not worked
      } else {
        // talkingClipAction.crossFadeTo(wavingClipAction, 1, true); not worked

This here gives a better “transition” - at least it does not try to go to the T-pose:

      if (proxy.isTalking) {
      } else {

what does reset() mean here? go back to the pose without animation applied? (T-pose in my case)

Hey, I have since tested what I suggested at the beginning, and it works.

Animation Controller : https://sbcode.net/react-three-fiber/animation-controller/

haha the fancy pose got me.
thx for the example! <3