Files
engine/docs/zh/animation/examples/controlAnimationByInput.mdx
luzhuang 2f7dd2b289 doc: opt animator doc (#2432)
Opt animator doc
2024-12-06 10:42:05 +08:00

137 lines
6.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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-0](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*WUbLQbY8qiAAAAAAAAAAAAAADsJ_AQ/original)
![image](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*1x7zS7WqTasAAAAAAAAAAAAADsJ_AQ/original)
## 1. 添加动画控制参数
为了能够根据用户输入控制动画,首先需要给 `动画控制器` 加一些参数,根据这些参数来切换 `动画状态` 。
1. 切换到 `Parameters` 面板
![image-5](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*rzRbRoI8_zEAAAAAAAAAAAAADsJ_AQ/original)
2. 点击 `+` 添加一个浮点参数 `speed`,并将默认值设置为 0。
![image-4](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*o6IhT6KdSZoAAAAAAAAAAAAADsJ_AQ/original)
## 2. 添加过渡条件
之前为大家介绍了如何在 `动画状态机` 中添加 `动画过渡`[详细介绍](/docs/animation/examples/crossFade/)),在之前的示例中,时间超过了 `ExitTime` 就会触发过渡。这里我们需要根据用户输入来触发过渡,所以我们需要添加一个 `过渡条件` 。
1. 在 `动画状态机` 中,选中从 `idle` 到 `walk` 的过渡,点击 `Add Condition` 添加一个 `Condition`。
![2024-11-08 10.53.40.gif](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`。
![2024-11-08 10.58.50.gif](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*an4WR66LO9kAAAAAAAAAAAAADsJ_AQ/original)
3. 选中 `run` 到 `exit` 的过渡,添加一个 `Condition` ,使其 `speed` 为 0 时,从 `run` 退出动画,重新回到 `idle`。
![2024-11-08 11.03.43.gif](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*YjqXSb1EDaIAAAAAAAAAAAAADsJ_AQ/original)
### 3. 添加脚本
我们需要一个脚本来接收用户输入,并根据用户输入来修改 `speed` 参数的值,以触发动画状态的切换。
添加脚本有两种方式:
1. 右键点击 **[资产面板](/docs/assets/interface)** 中的空白处,选择 `Create` -> `New Empty Script`
![image-3](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*vcaYR6cXhyAAAAAAAAAAAAAADsJ_AQ/original)
2. 点击添加资产按钮 `+`,选择 `New Empty Script`
![image-2](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-6](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*MOlaTKEGBYEAAAAAAAAAAAAADsJ_AQ/original)
### 5. 预览动画
与之前的教程不同,因为本次我们为实体添加了脚本,仅点击预览动画按钮,脚本代码是不会生效的,我们需要点击项目预览(项目预览才会编译脚本文件)按钮来预览动画。
![image-7](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*lAeHQITR98QAAAAAAAAAAAAADsJ_AQ/original)
当角色处于 `idle` 状态时,按下 `W` 键,角色会从 `idle` 过渡到 `walk`,按住 `Shift` 键,角色会从 `walk` 过渡到 `run`,松开 `W` 键,角色会从 `run` 退出动画,重新回到 `idle`。
![2024-11-08 15.43.37.gif](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` 也需要添加过渡。
![2024-11-08 14.26.00.gif](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*M-JsSawhoXUAAAAAAAAAAAAADsJ_AQ/original)
再次预览,我们发现 `walk` 到 `idle` 和 `run` 到 `walk` 的过渡效果已经生效了。
![2024-11-08 14.34.27.gif](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。
![2024-11-08 14.38.41.gif](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*uqwGQb4AHeUAAAAAAAAAAAAADsJ_AQ/original)
这样当我们同时松开 `W` 键和 `Shift` 键时,角色就会从 `run` 直接过渡到 `idle` 了。