在 Three.js 中,如果一个 3D 模型文件包含多个动画(例如 GLTF 文件中的多个 AnimationClip),你可以将这些动画收集到一个数组中,并通过代码逐一调用或管理它们。以下是详细的说明和实现方法。
结论
可以将模型文件中的多个动画收集为一个数组,并在 Three.js 中通过 THREE.AnimationMixer 和 THREE.AnimationAction 来管理和播放这些动画。
详细展开
1. 加载模型中的动画剪辑
当使用 GLTFLoader 加载模型时,模型文件中的所有动画剪辑会被自动解析并存储在 gltf.animations 数组中。你可以直接访问这个数组来获取所有动画。
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
const loader = new GLTFLoader();
loader.load('model.glb', (gltf) => {
const model = gltf.scene; // 获取模型对象
const animations = gltf.animations; // 获取动画剪辑数组
console.log('模型包含的动画:', animations);
});
2. 创建动画混合器
为了播放动画,需要为模型创建一个 THREE.AnimationMixer 实例。每个动画剪辑可以通过 mixer.clipAction(clip) 方法创建一个对应的 AnimationAction 对象。
const mixer = new THREE.AnimationMixer(model); // 创建动画混合器
3. 将动画收集到数组中
你可以将所有动画剪辑的 AnimationAction 对象存储在一个数组中,以便后续管理和调用。
const animationActions = []; // 用于存储所有动画动作
animations.forEach((clip, index) => {
const action = mixer.clipAction(clip); // 为每个动画剪辑创建动作
animationActions.push(action); // 将动作添加到数组中
console.log(`动画 ${index}:`, clip.name || `未命名动画 ${index}`);
});
4. 播放特定动画
通过索引或名称从数组中选择某个动画并播放。
// 播放第一个动画
if (animationActions.length > 0) {
animationActions[0].play();
}
// 或者根据名称播放动画
const targetAnimationName = 'run'; // 假设有一个名为 "run" 的动画
const targetAction = animationActions.find(action => action.getClip().name === targetAnimationName);
if (targetAction) {
targetAction.play();
} else {
console.warn(`未找到名为 "${targetAnimationName}" 的动画`);
}
5. 切换动画
可以通过停止当前动画并播放新动画来实现动画切换。
function switchToAnimation(index) {
// 停止所有正在播放的动画
animationActions.forEach(action => action.stop());
// 播放指定索引的动画
if (animationActions[index]) {
animationActions[index].play();
} else {
console.warn(`索引 ${index} 超出范围`);
}
}
// 示例:切换到第二个动画
switchToAnimation(1);
6. 淡入淡出切换动画
使用 crossFadeTo 方法可以在两个动画之间进行平滑过渡。
function fadeToAnimation(targetIndex, duration = 1) {
// 找到目标动画
const targetAction = animationActions[targetIndex];
if (!targetAction) {
console.warn(`索引 ${targetIndex} 超出范围`);
return;
}
// 遍历所有动画,停止其他动画并淡入目标动画
animationActions.forEach((action, index) => {
if (index !== targetIndex && action.isRunning()) {
action.crossFadeTo(targetAction, duration); // 淡出当前动画
}
});
targetAction.play(); // 播放目标动画
}
// 示例:淡入到第三个动画,持续时间 2 秒
fadeToAnimation(2, 2);
7. 完整示例代码
以下是一个完整的示例,展示如何加载模型、收集动画并切换动画:
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
const loader = new GLTFLoader();
loader.load('model.glb', (gltf) => {
const model = gltf.scene;
scene.add(model);
const animations = gltf.animations; // 获取动画剪辑数组
const mixer = new THREE.AnimationMixer(model); // 创建动画混合器
const animationActions = []; // 存储动画动作
animations.forEach((clip, index) => {
const action = mixer.clipAction(clip); // 创建动画动作
animationActions.push(action);
console.log(`加载动画 ${index}:`, clip.name || `未命名动画 ${index}`);
});
// 默认播放第一个动画
if (animationActions.length > 0) {
animationActions[0].play();
}
// 切换到第二个动画
function switchToSecondAnimation() {
if (animationActions.length > 1) {
switchToAnimation(1);
}
}
// 更新动画
let clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
mixer.update(clock.getDelta()); // 更新动画混合器
renderer.render(scene, camera);
}
animate();
});
总结
在 Three.js 中,可以将模型文件中的多个动画收集到一个数组中,并通过 THREE.AnimationMixer 和 THREE.AnimationAction 来管理和播放这些动画。通过这种方式,你可以轻松实现动画的切换、淡入淡出等效果,从而增强场景的交互性和视觉表现力。
2. 分享目的仅供大家学习和交流,请不要用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性
GLB下载网 - GLB/GLTF模型与格式资源免费下载,支持在线浏览与转换 » threejs 将3d模型动画收集为数组,按需调用
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载要提取码
- 分享过期和重复下载怎么办
- 模型和平台不兼容怎么办