基础知识
根据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