Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: opt animator doc #2432

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/zh/animation/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"examples": {
"title": "指南和示例"
}
}
118 changes: 61 additions & 57 deletions docs/zh/animation/animator.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ label: Animation
---

## 简介
动画控制组件([Animator](/apis/core/#Animator))的作用是读取[动画控制器](/docs/animation/animatorController/)([AnimatorController](/apis/core/#AnimatorController))的数据,并播放其内容。
`动画控制组件`([API](/apis/core/#Animator))的作用是读取 `动画控制器`([详细介绍](/docs/animation/animatorController/))的数据,并播放其内容。

### 参数说明

Expand All @@ -16,65 +16,88 @@ label: Animation

## 编辑器使用

当把模型拖入到场景中,模型以初始姿态展示,并不会播放任何动画,这时需要在模型实体上找到动画控制组件([Animator](/apis/core/#Animator))并为它绑定一个 [动画控制器](/docs/animation/animatorController/) 资产。
当把模型拖入到场景中,模型以初始姿态展示,并不会播放任何动画,这时需要在模型实体上找到 `动画控制组件` 并为它绑定一个 `动画控制器` 资产。


1. 找到或者创建动画控制组件([Animator](/apis/core/#Animator))
1. 找到或者创建 `动画控制组件`


<Callout type="info">
模型的动画控制组件([Animator](/apis/core/#Animator))在glTF实例的根实体上,也就是编辑器的模型实体下的第一个子实体上
模型的 `动画控制组件` 在glTF实例的根实体上,也就是编辑器的模型实体下的第一个子 `实体` 上

如果模型内有动画,会为你自动绑定一个只读的[动画控制器](/docs/animation/animatorController/)
如果模型内有动画,会为你自动绑定一个只读的 `动画控制器`
</Callout>

![alt text](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*WkafRagPFo8AAAAAAAAAAAAADsJ_AQ/original)

如果没有动画控制组件([Animator](/apis/core/#Animator))可以按下图方式创建
如果没有 `动画控制组件` 可以按下图方式创建
eyworldwide marked this conversation as resolved.
Show resolved Hide resolved

![alt text](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*uOuPT5cFwx4AAAAAAAAAAAAADsJ_AQ/original)
![image26](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*WFRXQIjZa0MAAAAAAAAAAAAADsJ_AQ/original)

2. 创建一个[动画控制器](/docs/animation/animatorController/) 资产并绑定到模型上
2. 创建一个 `动画控制器` 资产并绑定到模型上,创建 `动画控制器` 有两种方式:
1. 右键点击 **[资产面板](/docs/assets/interface)** 中的空白处,选择 `Create` -> `Animation Controller`

![alt text](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*PxHwTrU58yAAAAAAAAAAAAAADsJ_AQ/original)
![alt text](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*Ds5TTosYiDYAAAAAAAAAAAAADsJ_AQ/original)
![image9](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*61Q7S62IZxQAAAAAAAAAAAAADsJ_AQ/original)

3. 编辑动画控制器([详见](/docs/animation/animatorController/))后你就可以按照[动画控制器](/docs/animation/animatorController/) 的逻辑播放其中的动画了
2. 点击添加资产按钮 `+`,选择 `Animation Controller`

![image10](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*QqpxS6I9D90AAAAAAAAAAAAADsJ_AQ/original)

3. 在`动画控制组件` 的动画控制器属性上替换为刚才创建的 `动画控制器`

![image27](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*Y0pBQae4UWQAAAAAAAAAAAAADsJ_AQ/original)

4. 编辑 `动画控制器` 后(可以参考[动画控制器](/docs/animation/animatorController)文档)你就可以播放其中的动画了

## 脚本使用
<Callout type="positive">
在使用脚本之前,最好阅读[动画系统构成](/docs/animation/system)文档,以帮助你更好的了解动画系统的运行逻辑
</Callout>

在使用脚本之前,建议先阅读以下文档:

- [脚本](/docs/script/script)
- [动画系统构成](/docs/animation/system)

### 播放动画

在加载 GLTF 模型后引擎会自动为模型添加一个 Animator 组件,并将模型中的动画片段加入其中。可以直接在模型的根实体上获取 Animator 组件,并播放指定动画。
### 播放指定动画状态

你可以使用 [animator.play](/apis/core/#Animator-play) 方法来播放指定的 `动画状态`,参数说明详见[API 文档](/apis/core/#Animator-play)。

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

export default class extends Script {
onStart() {
const animator = this.entity.getComponent(Animator);
animator.play("State Name");
}
}
```

如果需要在动画中的某一时刻开始播放可以通过以下方式

```typescript
engine.resourceManager
.load<GLTFResource>(
"https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb"
)
.then((asset) => {
const { defaultSceneRoot } = asset;
rootEntity.addChild(defaultSceneRoot);
const animator = defaultSceneRoot.getComponent(Animator);
animator.play("run");
});
import { Script, Animator, Keys } from '@galacean/engine';

export default class extends Script {
onStart() {
const animator = this.entity.getComponent(Animator);
const layerIndex = 0;
const normalizedTimeOffset = 0.5; // 归一化的时间
animator.play("State Name", layerIndex, normalizedTimeOffset);
}
}
```

#### 控制播放速度
### 控制播放速度

你可以通过 [speed](/apis/core/#Animator-speed)  属性来控制动画的播放速度。 `speed`  默认值为 `1.0` ,值越大播放的越快,越小播放的越慢。当值为负数时,进行倒播。

```typescript
animator.speed = 2.0;
```

#### 停止/重新播放
### 停止/重新播放

你可以通过设置 Animator 的 [enabled](/apis/core/#Animator-enabled) 来停止和重新播放动画
你可以通过设置 [animator.enabled](/apis/core/#Animator-enabled) 来停止和重新播放动画

```typescript
// 停止
Expand All @@ -83,8 +106,8 @@ animator.enabled = false;
animator.enabled = true;
```

#### 暂停/恢复播放
你可以通过设置 Animator 的 [speed](/apis/core/#Animator-speed) 暂停和恢复播放
### 暂停/恢复播放
你可以通过设置 [animator.speed](/apis/core/#Animator-speed) 暂停和恢复播放

```typescript
// 暂停
Expand All @@ -94,44 +117,25 @@ animator.speed = 1;
```


如果你只想针对某一个动画状态进行暂停,可以通过将它的速度设置为 0 来实现。
如果你只想针对某一个 `动画状态` 进行暂停,可以通过将它的速度设置为 0 来实现。

```typescript
const state = animator.findAnimatorState("xxx");
state.speed = 0;
```

#### 播放指定动画状态

你可以使用 [animator.play](/apis/core/#Animator-play) 方法来播放指定的 `AnimatorState`,参数说明详见[API 文档](/apis/core/#Animator-play)。

```typescript
animator.play("run");
```

如果需要在动画中的某一时刻开始播放可以通过以下方式

```typescript
const layerIndex = 0;
const normalizedTimeOffset = 0.5; // 归一化的时间
animator.play("run", layerIndex, normalizedTimeOffset);
```

<Playground href="/embed/skeleton-animation-play" />

#### 过渡指定动画状态
### 过渡指定动画状态

你可以使用 [animator.crossfade](/apis/core/#Animator-crossfade) 方法来将动画过渡到指定的 `AnimatorState`,参数说明详见[API 文档](/apis/core/#Animator-crossFade)。
你可以使用 [animator.crossfade](/apis/core/#Animator-crossfade) 方法来将动画过渡到指定的 `动画状态`,参数说明详见[API 文档](/apis/core/#Animator-crossFade)。

```typescript
animator.crossFade("run", 0.3);
animator.crossFade("OtherStateName", 0.3);
```

<Playground href="/embed/skeleton-animation-crossfade" />

### 获取当前在播放的动画状态

你可以使用 [getCurrentAnimatorState](/apis/core/#Animator-getCurrentAnimatorState)  方法来获取当前正在播放的 AnimatorState。参数为动画状态所在层的序号`layerIndex`, 详见[API 文档](/apis/core/#Animator-getCurrentAnimatorState)。获取之后可以设置动画状态的属性,比如将默认的循环播放改为一次。
你可以使用 [getCurrentAnimatorState](/apis/core/#Animator-getCurrentAnimatorState)  方法来获取当前正在播放的 `动画状态`。参数为 `动画状态` 所在 `动画层` 的序号`layerIndex`, 详见[API 文档](/apis/core/#Animator-getCurrentAnimatorState)。获取之后可以设置 `动画状态` 的属性,比如将默认的循环播放改为一次。

```typescript
const currentState = animator.getCurrentAnimatorState(0);
Expand All @@ -143,7 +147,7 @@ currentState.wrapMode = WrapMode.Loop;

### 获取动画状态

你可以使用 [findAnimatorState](/apis/core/#Animator-findAnimatorState)  方法来获取指定名称的 AnimatorState。详见[API 文档](/apis/core/#Animator-getCurrentAnimatorState)。获取之后可以设置动画状态的属性,比如将默认的循环播放改为一次。
你可以使用 [findAnimatorState](/apis/core/#Animator-findAnimatorState)  方法来获取指定名称的 `动画状态` 。获取之后可以设置动画状态的属性,比如将默认的循环播放改为一次。

```typescript
const state = animator.findAnimatorState("xxx");
Expand All @@ -154,6 +158,6 @@ state.wrapMode = WrapMode.Loop;
```

### 动画裁剪
你可以通过设置 [Animator](/apis/core/#Animator) 的 [cullingMode](/apis/core/#Animator-cullingMode) 来设置当 Animator 绑定的实体不可见时动画是否进行计算。在动画被裁剪时,动画不会进行计算并应用到实体上,但动画的状态仍然会随着时间更新,使其再可见时是正确地表现。
你可以通过设置 `动画控制组件` 的 [cullingMode](/apis/core/#Animator-cullingMode) 来设置当 `实体` 不可见时动画是否进行计算。在动画被裁剪时,动画不会进行计算并应用到 `实体` 上,但动画的状态仍然会随着时间更新,使其再可见时是正确地表现。


56 changes: 39 additions & 17 deletions docs/zh/animation/animatorController.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,47 @@ title: 动画控制器
type: 动画
label: Animation
---
## 简介

动画控制器([AnimatorController](/apis/core/#AnimatorController))可以帮助你为角色或其他动画对象组织一组动画的播放逻辑。
它通过[动画状态机](/docs/animation/state-machine/)([AnimatorStateMachine](/apis/core/#AnimatorStateMachine))像流程图一样可视化的组织动画对象的动画播放逻辑,并在符合条件时自动切换动画状态([AnimatorState](/apis/core/#AnimatorState))并播放引用的[动画片段](/docs/animation/clip)([AnimationClip](/apis/core/#AnimationClip))。
`动画控制器`([API](/apis/core/#AnimatorController))可以帮助你为角色或其他动画对象组织一组动画的播放逻辑。
它通过 `动画状态机`([详细介绍](/docs/animation/state-machine/))像流程图一样可视化的组织动画对象的动画播放逻辑,并在符合条件时自动切换 `动画状态` 并播放引用的 `动画片段`([详细介绍](/docs/animation/clip/))。

### 主要组成部分
#### 动画层
`动画层` 用于在一个 `动画控制器` 中组织和管理 `动画状态机` ,每个 `动画层` 都有其自己的 `动画状态机`。
在 `动画控制组件` 运行时所有的 `动画层` 同时运行,通过 `混合权重` 及 `混合模式` 控制各个 `动画层` 对整体动画的影响。关于 `动画层` 的使用请参考[动画层](/docs/animation/layer/)文档。

#### 动画参数
`动画参数` 用于控制 `动画状态机` 的 `动画状态` 切换,通过设置 `动画参数` 的值满足 `动画过渡` 的条件时,`动画过渡` 会触发,从而切换到目标 `动画状态`。关于 `动画参数` 的使用请参考[动画状态机](/docs/animation/state-machine/)文档。

## 编辑器使用

通过动画控制器的编辑器,用户可以在其中组织[动画片段](/docs/animation/clip)的播放逻辑
通过 `动画控制器` 的编辑器,用户可以在其中组织 `动画片段`([详细介绍](/docs/animation/clip))的播放逻辑
eyworldwide marked this conversation as resolved.
Show resolved Hide resolved

1. 准备好 `动画片段`([详细介绍](/docs/animation/clip))

![1.jpg](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*lq8jQIgm_-cAAAAAAAAAAAAADsJ_AQ/original)

2. 要组织播放这些 `动画片段` 我们需要创建一个 `动画控制器` 资产,创建 `动画控制器` 有两种方式:
1. 右键点击 **[资产面板](/docs/assets/interface)** 中的空白处,选择 `Create` -> `Animation Controller`

![image9](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*61Q7S62IZxQAAAAAAAAAAAAADsJ_AQ/original)

1. 准备好动画片段([制作动画片段](/docs/animation/clip))
2. 点击添加资产按钮 `+`,选择 `Animation Controller`

![alt text](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*Wl35T7U_zg8AAAAAAAAAAAAADsJ_AQ/original)
![image10](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*QqpxS6I9D90AAAAAAAAAAAAADsJ_AQ/original)

2. 要组织播放这些动画片段我们需要创建一个动画控制器([AnimatorController](/apis/core/#AnimatorController))资产
3. 刚创建的 `动画控制器` 中没有任何数据,我们需要对他进行编辑,双击资产, 并为它添加一个 `动画状态`([详细介绍](/docs/animation/state-machine/#动画状态))

![alt text](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*PxHwTrU58yAAAAAAAAAAAAAADsJ_AQ/original)
![2.jpg](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*7bZmS4iZ10gAAAAAAAAAAAAADsJ_AQ/original)

3. 刚创建的动画控制器中没有任何数据,我们需要对他进行编辑,双击资产, 并为它添加一个动画状态([AnimatorState](/apis/core/#AnimatorState))
![alt text](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*V0n1TJMquGYAAAAAAAAAAAAADsJ_AQ/original)
4. 点击添加的 `动画状态` 为它绑定一个 `动画片段`([详细介绍](/docs/animation/clip))

4. 点击 AnimatorState 为它绑定一个[动画片段](/docs/animation/clip)([AnimationClip](/apis/core/#AnimationClip))
![alt text](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*xfPTRJg-hOMAAAAAAAAAAAAADsJ_AQ/original)

5. 在[动画控制组件](/docs/animation/animator)上绑定该动画控制器([AnimatorController](/apis/core/#AnimatorController))资产
![alt text](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*Ds5TTosYiDYAAAAAAAAAAAAADsJ_AQ/original)
5. 在 `动画控制组件`([详细介绍](/docs/animation/animator))上绑定该 `动画控制器` 资产

![3.jpg](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*H_ShSaWEXtIAAAAAAAAAAAAADsJ_AQ/original)

6. 至此你在导出的项目中就可以通过 `animator.play("New State")` 播放 `Idle` 动画了

Expand All @@ -37,13 +54,18 @@ label: Animation

## 脚本使用

<Callout type="positive">
在使用脚本之前,最好阅读[动画系统构成](/docs/animation/system)文档,以帮助你更好的了解动画系统的运行逻辑
</Callout>
在使用脚本之前,建议先阅读以下文档:

- [脚本](/docs/script/script)
- [动画系统构成](/docs/animation/system)

### 绑定动画控制器

你可以通过 [animator.animatorController](/apis/core/#Animator-animatorController)  属性来为 [Animator](/apis/core/#Animator) 绑定动画控制器。加载完成的 glTF 模型如果有动画数据会为每个glTF实例自动绑定一个默认的 AnimatorController。
你可以通过 [animator.animatorController](/apis/core/#Animator-animatorController)  属性来为 [Animator](/apis/core/#Animator) 绑定 `动画控制器` 。

<Callout type="info">
加载完成的 glTF 模型如果有动画数据引擎会为每个glTF实例自动绑定一个默认的 `动画控制器`,你可以直接使用播放其内的动画。
</Callout>

```typescript
animator.animatorController = new AnimatorController(engine);
Expand All @@ -52,7 +74,7 @@ animator.play("New State");

#### 复用动画数据

Animator 的 [animatorController](/apis/core/#AnimatorController) 就是一个数据存储的类,它不会包含运行时的数据。基于这种设计只要绑定 Animator 组件的模型的**骨骼节点的层级结构和命名相同**,我们就可以使用此模型的动画数据进行复用。
`动画控制器` 就是一个存储数据的类,它不会包含运行时的数据。基于这种设计只要绑定 `动画控制组件` 的模型的**骨骼节点的层级结构和命名相同**,我们就可以使用此模型的动画数据进行复用。

```typescript
const animator = model1.getComponent(Animator);
Expand Down
1 change: 1 addition & 0 deletions docs/zh/animation/clip-for-artist.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,4 @@ Unity 也可以导出动画切片,但是效率比较低。
<img src="https://gw.alipayobjects.com/zos/OasisHub/1bfefe2b-ca58-4cca-a091-9efe8028a4df/1622552925151-16b86fcc-4680-4611-aa32-d3697bbe5086.png" alt="image.png" style="zoom:50%;" />

12. 至此,制作的动画切片 glTF 文件导出完毕,可以访问 Galacean 的 [glTF 预览](https://galacean.antgroup.com/engine/gltf-viewer) 进行功能校验。

Loading
Loading