Three.js 框架中的 AnimationMixer 使用详解

person 少陵野老    watch_later 2024-10-12 21:47:31
visibility 78    class AnimationMixer    bookmark 专栏

AnimationMixer 是 Three.js 动画系统中的核心组件,用于管理、播放和混合多个 AnimationClip(动画片段)。通过 AnimationMixer,我们可以对动画进行精确的控制,包括播放、暂停、停止和混合多个动画效果。本文将详细介绍 AnimationMixer 的使用方法,涵盖其属性、方法,并结合 AnimationClipAnimationAction 展示动画的创建和控制。

1. 什么是 AnimationMixer?

AnimationMixer 是一个动画混合器类,主要负责管理场景中一个 3D 对象(如网格、骨骼等)的动画。一个对象可以包含多个动画片段(AnimationClip),AnimationMixer 提供了接口来对这些动画进行播放、暂停、停止和混合等操作。

1.1 适用场景

  • 动画播放管理:控制动画的播放、暂停、停止。
  • 动画混合:允许多个动画同时播放,并通过权重来混合不同的动画效果。
  • 精确控制:可以通过时间参数来精确控制动画的进度和循环。

2. 使用 AnimationMixer 的基本步骤

要使用 AnimationMixer,我们通常需要执行以下步骤:

  1. 创建一个 3D 对象(如 Mesh)。
  2. 创建关键帧动画片段(AnimationClip)。
  3. 创建 AnimationMixer 并将其绑定到 3D 对象。
  4. 使用 AnimationMixer 创建并控制动画实例(AnimationAction)。
  5. 在渲染循环中更新 AnimationMixer

下面,我们将通过示例逐步展示这些操作。

3. 初始化场景和对象

首先,我们需要创建一个基本的 Three.js 场景,设置渲染器、摄像机和一个简单的几何对象。为了演示,我们将使用一个简单的立方体。

3.1 创建场景

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.z = 5;

3.2 创建 3D 对象

创建一个简单的立方体,并将其添加到场景中。

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

4. 创建 AnimationClip

AnimationClip 定义了动画的内容,它由一组关键帧(KeyframeTrack)组成。在这个示例中,我们将使用 VectorKeyframeTrack 来控制立方体沿 Y 轴的移动。

const times = [0, 1, 2];  // 定义动画时间点
const values = [0, 0, 0, 0, 2, 0, 0, 0, 0];  // 在不同时间点的位置
const positionKF = new THREE.VectorKeyframeTrack('.position', times, values);

// 创建 AnimationClip
const clip = new THREE.AnimationClip('moveUp', 2, [positionKF]);

5. 创建 AnimationMixer 并播放动画

现在,我们需要创建 AnimationMixer 并将其绑定到我们的立方体对象,然后通过它来播放动画。

5.1 创建 AnimationMixer

AnimationMixer 需要绑定到一个 3D 对象(在本例中是立方体 cube),从而控制其动画。

const mixer = new THREE.AnimationMixer(cube);

5.2 创建 AnimationAction 并播放动画

使用 AnimationMixerclipAction 方法创建一个 AnimationAction,并调用 play() 方法开始播放动画。

const action = mixer.clipAction(clip);
action.play();

6. 更新 AnimationMixer

在渲染循环中,我们需要不断更新 AnimationMixer 以驱动动画。可以通过 Clock 来计算每一帧的时间差,并将其传递给 mixer.update()

const clock = new THREE.Clock();

function animate() {
    requestAnimationFrame(animate);
  
    const delta = clock.getDelta();  // 获取时间增量
    mixer.update(delta);  // 更新动画混合器

    renderer.render(scene, camera);
}

animate();

7. AnimationMixer 的属性和方法详解

7.1 属性

  • timeAnimationMixer 的当前时间,通常通过 update() 方法自动更新。
  • timeScale:用于控制动画的时间比例,默认为 1。如果将 timeScale 设置为 0.5,动画播放速度将减半;设置为 2,则动画速度加倍。
mixer.timeScale = 0.5;  // 动画以半速播放

7.2 方法

  • clipAction(clip):创建一个 AnimationAction,用来控制 AnimationClip 的播放。
  • update(deltaTime):更新动画,deltaTime 是从上次更新到现在经过的时间。
  • stopAllAction():停止所有正在播放的动画。
  • uncacheClip(clip):从缓存中移除指定的 AnimationClip,通常用于节省内存。

8. AnimationAction 的详细用法

AnimationAction 是控制动画播放的关键组件,它由 AnimationMixer 创建并管理。通过 AnimationAction,我们可以控制动画的播放、暂停、停止、混合等行为。

8.1 播放和暂停动画

通过 play()pause() 方法,可以控制动画的播放和暂停。

action.play();  // 播放动画
action.paused = true;  // 暂停动画

8.2 动画的重复和循环

可以通过 setLoop() 方法设置动画的循环方式。Three.js 提供了三种循环模式:

  • THREE.LoopOnce:动画只播放一次。
  • THREE.LoopRepeat:动画重复播放。
  • THREE.LoopPingPong:动画来回播放。
action.setLoop(THREE.LoopPingPong, Infinity);  // 设置动画来回循环播放

8.3 混合动画

AnimationMixer 支持多个动画的混合播放。可以通过设置 AnimationActionweight 属性来控制不同动画的混合比例。

action.weight = 0.5;  // 设置当前动画的权重为 0.5

8.4 停止动画

通过 stop() 方法可以停止当前动画的播放。

action.stop();  // 停止动画

9. 复杂场景中的多动画混合

在实际项目中,我们通常需要为同一个对象创建多个动画,并在不同的时刻混合播放。AnimationMixer 提供了丰富的接口来实现这种需求。

9.1 创建第二个动画

我们再创建一个沿 X 轴移动的动画,并将其与之前的 Y 轴动画混合播放。

const times2 = [0, 1, 2];
const values2 = [0, 0, 0, 2, 0, 0, 0, 0, 0];
const positionKF2 = new THREE.VectorKeyframeTrack('.position', times2, values2);

const clip2 = new THREE.AnimationClip('moveSide', 2, [positionKF2]);

const action2 = mixer.clipAction(clip2);
action2.play();

9.2 动画权重的调整

我们可以通过调整 actionaction2weight 属性来实现动画的平滑过渡。

action.weight = 0.5;
action2.weight = 0.5;

这样,立方体将同时沿 Y 轴和 X 轴移动,产生对角线方向的移动效果。

10. 动画事件监听

AnimationMixer 允许我们监听动画播放过程中的事件,如动画完成、循环等。可以通过 mixer.addEventListener() 来监听这些事件。

10.1 监听动画结束事件

mixer.addEventListener('finished', (event) => {
    console.log('动画播放完成');
});

10.2 监听循环事件

我们还可以监听动画的循环事件,特别是在需要处理动画状态切换时非常有用。

mixer.addEventListener('loop', (event) => {
    console.log('动画循环');
});

11. 窗口大小调整的处理

在实际应用中,我们需要在窗口大小发生变化时,更新摄像机和渲染器的参数,以确保动画的正确显示。

window.addEventListener('

resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
});

12. 结论

AnimationMixer 是 Three.js 动画系统中的核心组件,提供了灵活的接口来管理、控制和混合动画。本文详细介绍了如何创建、使用 AnimationMixer,并通过多种示例展示了 AnimationClipAnimationAction 的综合使用。通过对动画时间、权重和循环的精确控制,我们可以创建出复杂、流畅的动画效果。

希望本文能够帮助你深入理解和掌握 Three.js 的动画系统!如果你有任何问题或建议,欢迎留言讨论。

评论区
评论列表
menu