Three.js实现加载动画应用于人物模型及动作切换

666 阅读1分钟

基础知识

根据Three.js文档-动画,动画有三个关键概念:

  • AnimationMixer:动画播放器,用于在场景中的特定对象上播放动画
  • AnimationAction:调度存储在 AnimationClips 中的动画
  • AnimationClip:一组可重复使用的表示动画的关键帧轨迹

仔细观察上面三个对应构造函数,AnimationMixer和AnimationAction都需要rootObject,即他们都与特定对象绑定,而AnimationClip则没有,推测可以从动作模型中获取到AnimationClip,使用人物模型的AnimationMixer.clipAction()方法得到人物模型的AnimationAction,然后播放。

从fbx、gltf格式中加载得到的mesh.animations即AnimationClip的数组。

至于动画的切换,只需要一个事件触发,加载不同的模型即可。

demo

    // 缓存
    const animationClips = {}
    const actionNames = ['Crying', 'Happy', 'Sad Idle', 'Standing Arguing', 'Standing Greeting']
    
    // 点击事件 动作切换
    function onMouseClick(event) {
      // 随机
      const actionName = actionNames[Math.floor(actionName.length * Math.random())]
      let animationClip = animationClips[actionName]
      if (animationClip) {
        console.log('已加载')
        let clipAction = manMixer.clipAction(animationClip).play()
        animationClip = clipAction.getClip()
      } else {
        const url = `assets/models/${actionName}.fbx`
        // 加载动作
        const loader = new THREE.FBXLoader()
        loader.load(url, function (mesh) {
          // 动作模型的animationClip
          animationClips[actionName] = mesh.animations[0]
          let animationClip = animationClips[actionName]
          // 使用人物模型的animationMixer
          const clipAction = manMixer.clipAction(animationClip)
          clipAnimation.play()
          animationClip = clipAction.getClip();
        },  res => {
          let progress = (res.loaded / res.total * 100).toFixed(0);
          console.log(url, progress)
        }, err => {
          console.log(err)
        })
      }
    }
    window.addEventListener('click', onMouseClick, false);

动作模型及人物模型来源:mixamo