Hello everyone, I have a question, how does the AnimationMixer animation play back and forth, just like table tennis

 <script>
      let renderer = new THREE.WebGLRenderer({
        canvas: document.querySelector("#cc"),
        antialias: true,
      });
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setClearColor(0xa0a0a0);
      renderer.shadowMap.enabled = true;
      let scene = new THREE.Scene();
      scene.fog = new THREE.Fog(0xa0a0a0, 200, 2000); //场景添加雾化功能

      let camera = new THREE.PerspectiveCamera(
        60,
        window.innerWidth / window.innerHeight,
        1,
        2000
      );
      camera.position.set(11, 143, 890);

      let clock = new THREE.Clock(); //设置时钟对象,后面方便调用。

      let c = new THREE.OrbitControls(camera, document.querySelector("#cc")); //设置控制器。方便操控3d世界。
      c.update();

      let light = new THREE.HemisphereLight(0xffffff, 0x444444);
      light.position.set(0, 200, 0);
      scene.add(light); //设置半球光,并添加进去

      let Dligth = new THREE.DirectionalLight(0xffffff, 1);
      Dligth.position.set(0, 200, 100);
      Dligth.castShadow = true;

      //设置相机渲染面积
      Dligth.shadow.camera.top = 180;
      Dligth.shadow.camera.bottom = -100;
      Dligth.shadow.camera.left = -120;
      Dligth.shadow.camera.right = 120;
      //设置阴影细腻度 长*宽
      Dligth.shadow.mapSize.width = 2048; // default
      Dligth.shadow.mapSize.height = 2048; // default
      scene.add(Dligth); //设置平行光,并添加进去

      let grid = new THREE.GridHelper(2000, 10, 0x708090, 0x708090); //设置地面网格辅助线、
      scene.add(grid);

      let ground = new THREE.Mesh(
        new THREE.PlaneBufferGeometry(2000, 2000),
        new THREE.MeshPhongMaterial({ color: 0xa9a9a9 })
      ); //设置地面
      ground.receiveShadow = true;
      // ground.position.set(0, -1, 0); //位置下调下,放置共面,网格线
      ground.rotation.x = -Math.PI / 2;

      scene.add(ground);
      let box, allDuration, timerLayer, action;
      loadFbx(); //加载模型动画
      draw();

      function draw() {
        requestAnimationFrame(draw);

        if (box) {
          box.mixer.update(clock.getDelta()); //判断模型加载后,进行动画渲染
        }

        renderer.render(scene, camera);
      }

      function loadFbx() {
        let loader = new THREE.FBXLoader();
        loader.load("fbx/Dying.FBX", (object) => {
          object.scale.set(5, 5, 5);
          object.mixer = new THREE.AnimationMixer(object); //动画播放器处理模型动画

          let animation = object.animations[0]; //动画
          allDuration = animation.duration; //动画时长
          timerLayer = allDuration / animation.tracks.length;
          action = object.mixer.clipAction(animation);
          object.traverse((e) => {
            if (e.isMesh) {
              e.castShadow = true;
              e.receiveShadow = true;
              e.material.transparent = false; //
            }
          });
          box = object;

          scene.add(box);
          domClick();

          action.loop = THREE.LoopOnce;
          action.clampWhenFinished = true;
          action.play();
        });
      }

      function domClick() {
        document.querySelector("#tack").addEventListener("click", () => {
          console.log("11111111");
          action.loop = THREE.LoopOnce;
          action.clampWhenFinished = true;
          action.setEffectiveTimeScale(-1).play();
        });
      }
    </script>
``` javascript

If you want to play an animation in reverse, you can set the timescale to a negative value, set loopOnce again, and play, and seeing you are looping once and clamping when finished, I guess you want to start again, possibly according to some state, so you can check for some variable in an if block, and loop it backwards

if (variable) {
  actions.myAction.reset();
  actions.myAction.clampWhenFinished = true;
  actions.myAction.timeScale = 1;
  actions.myAction.setLoop(THREE.LoopOnce).play();
} else {
  actions.myAction.clampWhenFinished = true;
  actions.myAction.paused = false;
  actions.myAction.timeScale = -1;
  actions.myAction.setLoop(THREE.LoopOnce).play();
}

Thank you very much, the else code block, when timeScale = -1, it will stop for a while before running, do you know the reason for this?

glad to help! It’s hard to say why that would be happening, but maybe you have some extra frames at the end of the animation? If not I am afraid I would need to see how you implemented the code.

Thank you! Maybe there is something wrong with my model, find the reason