---
order: 4
title: 用户输入控制动画
type: 动画
group: 指南和示例
label: Animation/Examples
---

本示例展示了如何在 Galacean 编辑器中让用户的输入控制动画。通过简单的步骤，你将学习如何结合用户输入来控制动画的切换，让角色根据用户的交互进行相应的动作过渡。
如果你是第一次使用动画编辑器，建议先阅读前面几篇文档：

[1.播放模型中的动画](/docs/animation/examples/playAnimation/)

[2.动画复用](/docs/animation/examples/reuseAnimation/)

[3.动画过渡](/docs/animation/examples/crossFade/)

## 0. 准备工作

1. 在开始之前，我们需要有一个包含多个动画的模型， 并将其拖入到场景中。如果你没有模型，可以在点此下载 [模型](https://mdn.alipayobjects.com/oasis_be/afts/file/A*N99IQYh_g5YAAAAAAAAAAAAADkp5AQ/player.glb)。

2. 我们要有一个已编辑好动画过渡的 `动画控制器` 。请参考：[编辑动画控制器](/docs/animation/examples/crossFade/#3-编辑动画控制器)。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*WUbLQbY8qiAAAAAAAAAAAAAADsJ_AQ/original" />

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*1x7zS7WqTasAAAAAAAAAAAAADsJ_AQ/original" />

## 1. 添加动画控制参数

为了能够根据用户输入控制动画，首先需要给 `动画控制器` 加一些参数，根据这些参数来切换 `动画状态` 。

1. 切换到 `Parameters` 面板

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*rzRbRoI8_zEAAAAAAAAAAAAADsJ_AQ/original" />

2. 点击 `+` 添加一个浮点参数 `speed`，并将默认值设置为 0。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*o6IhT6KdSZoAAAAAAAAAAAAADsJ_AQ/original" />

## 2. 添加过渡条件

之前为大家介绍了如何在 `动画状态机` 中添加 `动画过渡`（[详细介绍](/docs/animation/examples/crossFade/)），在之前的示例中，时间超过了 `ExitTime` 就会触发过渡。这里我们需要根据用户输入来触发过渡，所以我们需要添加一个 `过渡条件` 。

1. 在 `动画状态机` 中，选中从 `idle` 到 `walk` 的过渡，点击 `Add Condition` 添加一个 `Condition`。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*Z-P8SqQynhMAAAAAAAAAAAAADsJ_AQ/original" />

`Condition` 的默认值刚好符合我们的需求，当 `speed` 大于 0 时，就会从 `idle` 过渡到 `walk`。

2. 同样的，选中从 `walk` 到 `run` 的过渡，添加一个 `Condition`，使其 `speed` 大于 5 时，从 `walk` 过渡到 `run`。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*an4WR66LO9kAAAAAAAAAAAAADsJ_AQ/original" />

3. 选中 `run` 到 `exit` 的过渡，添加一个 `Condition` ，使其 `speed` 为 0 时，从 `run` 退出动画，重新回到 `idle`。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*YjqXSb1EDaIAAAAAAAAAAAAADsJ_AQ/original" />

### 3. 添加脚本
我们需要一个脚本来接收用户输入，并根据用户输入来修改 `speed` 参数的值，以触发动画状态的切换。
添加脚本有两种方式：

1. 右键点击 **[资产面板](/docs/assets/interface)** 中的空白处，选择 `Create` -> `New Empty Script`

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*vcaYR6cXhyAAAAAAAAAAAAAADsJ_AQ/original" />

2. 点击添加资产按钮 `+`，选择 `New Empty Script`

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*ukTPS6vXR54AAAAAAAAAAAAADsJ_AQ/original" />

### 4. 编辑并绑定脚本
1. 双击脚本，打开脚本编辑器，输入以下代码：

```typescript
import { Script, Animator, Keys } from '@galacean/engine';

export default class extends Script {
  animator: Animator;
  onStart() {
    this.animator = this.entity.getComponent(Animator);
  }

  onUpdate(deltaTime: number) {
    const inputManager = this.engine.inputManager;
    if (inputManager.isKeyHeldDown(Keys.KeyW)) {
        // 如果用户按下 W + Shift 键，则设置 speed 参数值为 6
      if (inputManager.isKeyHeldDown(Keys.ShiftLeft)) {
        this.animator.setParameterValue('speed', 6);
      } else {
        // 如果用户仅按住 W 键，则设置 speed 参数值为 1
        this.animator.setParameterValue('speed', 1);
      }
    }

    // 如果用户松开 W 键，则设置 speed 参数值为 0
    if (inputManager.isKeyUp(Keys.KeyW)) {
      this.animator.setParameterValue('speed', 0);
    }
  }
}
```

关于脚本的详细说明请参考：[脚本](/docs/script/script)

关于用户输入的详细说明请参考：[交互总览](/docs/input/input)

2. 找到 `Animator` 组件所在的实体，为其添加刚刚创建的脚本。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*MOlaTKEGBYEAAAAAAAAAAAAADsJ_AQ/original" />

### 5. 预览动画
与之前的教程不同，因为本次我们为实体添加了脚本，仅点击预览动画按钮，脚本代码是不会生效的，我们需要点击项目预览（项目预览才会编译脚本文件）按钮来预览动画。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*lAeHQITR98QAAAAAAAAAAAAADsJ_AQ/original" />

当角色处于 `idle` 状态时，按下 `W` 键，角色会从 `idle` 过渡到 `walk`，按住 `Shift` 键，角色会从 `walk` 过渡到 `run`，松开 `W` 键，角色会从 `run` 退出动画，重新回到 `idle`。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*RQLbRZPlfUEAAAAAAAAAAAAADsJ_AQ/original" />

### 6. 优化动画
我们预览时会发现，如果我们在 `walk` 状态时松开 `W` 键，角色并不会切换到 `idle` 状态，而是继续播放 `walk` 动画。这是因为我们并没有从 `walk` 到 `idle` 的过渡。
而且从 `run` 到 `idle` 也没有过渡效果。因为我们是通过重新进入 `entry` 切换到 `idle` 的，而 `entry` 到 `idle` 的过渡的 `Duration` 是 0。想要从 `run` 过渡到 `idle` ，我们可以将 `run` 连接到 `idle`。
同理想要从 `run` 过渡到 `walk` 也需要添加过渡。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*M-JsSawhoXUAAAAAAAAAAAAADsJ_AQ/original" />

再次预览，我们发现 `walk` 到 `idle` 和 `run` 到 `walk` 的过渡效果已经生效了。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*b3b1QrhhzqkAAAAAAAAAAAAADsJ_AQ/original" />

但是从 `run` 到 `idle` 的过渡效果并没有生效，而是先到 `walk` 再由 `walk` 到 `idle`，这是因为当 `speed` 参数为 0 时，`run` 到 `walk ` 和 `run` 到 `idle` 的 `Condition` 都满足。
为了避免这种情况，我们可以给 `run` 到 `walk` 再添加一个 `Condition` 并将其设置为 `speed` 大于 0。

<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*uqwGQb4AHeUAAAAAAAAAAAAADsJ_AQ/original" />

这样当我们同时松开 `W` 键和 `Shift` 键时，角色就会从 `run` 直接过渡到 `idle` 了。

