threejs 将3d模型动画收集为数组,按需调用

  • 正文概述
  • 在 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 来管理和播放这些动画。通过这种方式,你可以轻松实现动画的切换、淡入淡出等效果,从而增强场景的交互性和视觉表现力。

    1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
    2. 分享目的仅供大家学习和交流,请不要用于商业用途!
    3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
    4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
    5. 如有链接无法下载、失效或广告,请联系管理员处理!
    6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
    7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
    8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
    声明如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性

    GLB下载网 - GLB/GLTF模型与格式资源免费下载,支持在线浏览与转换 » threejs 将3d模型动画收集为数组,按需调用

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载要提取码
    百度网盘提取码都是gltf。
    分享过期和重复下载怎么办
    分享过期请使用备份下载,重复下载是不另扣费的,请放心下载。
    模型和平台不兼容怎么办
    可以用网站在线编辑功能,修改模型属性,大小,方向,坐标,中心,透明等问题,然后重新导出既可https://glbxz.com/38636.html
    开通VIP 享更多特权,建议使用 QQ 登录