mirror of
https://github.com/galacean/engine.git
synced 2026-05-14 14:36:41 +08:00
137 lines
6.9 KiB
Plaintext
137 lines
6.9 KiB
Plaintext
---
|
||
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-编辑动画控制器)。
|
||
|
||

|
||
|
||

|
||
|
||
## 1. 添加动画控制参数
|
||
|
||
为了能够根据用户输入控制动画,首先需要给 `动画控制器` 加一些参数,根据这些参数来切换 `动画状态` 。
|
||
|
||
1. 切换到 `Parameters` 面板
|
||
|
||

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

|
||
|
||
## 2. 添加过渡条件
|
||
|
||
之前为大家介绍了如何在 `动画状态机` 中添加 `动画过渡`([详细介绍](/docs/animation/examples/crossFade/)),在之前的示例中,时间超过了 `ExitTime` 就会触发过渡。这里我们需要根据用户输入来触发过渡,所以我们需要添加一个 `过渡条件` 。
|
||
|
||
1. 在 `动画状态机` 中,选中从 `idle` 到 `walk` 的过渡,点击 `Add Condition` 添加一个 `Condition`。
|
||
|
||

|
||
|
||
`Condition` 的默认值刚好符合我们的需求,当 `speed` 大于 0 时,就会从 `idle` 过渡到 `walk`。
|
||
|
||
2. 同样的,选中从 `walk` 到 `run` 的过渡,添加一个 `Condition`,使其 `speed` 大于 5 时,从 `walk` 过渡到 `run`。
|
||
|
||

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

|
||
|
||
### 3. 添加脚本
|
||
我们需要一个脚本来接收用户输入,并根据用户输入来修改 `speed` 参数的值,以触发动画状态的切换。
|
||
添加脚本有两种方式:
|
||
|
||
1. 右键点击 **[资产面板](/docs/assets/interface)** 中的空白处,选择 `Create` -> `New Empty Script`
|
||
|
||

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

|
||
|
||
### 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` 组件所在的实体,为其添加刚刚创建的脚本。
|
||
|
||

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

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

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

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

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

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