Skip to content

Commit b30c8ba

Browse files
committed
docs: today's creation surfaces reach the guides, EN + zh
Animation: the Flipbook editor workflow (Create Sprite Animation, grid slicing, frame strip, Create Animated Sprite, edit-mode viewport preview), the SpriteAnimator finished flag, and code-free state switching via the spriteAnim.* built-ins. AI: the new optional action argument and the four spriteAnim built-ins. Audio: bus effect chains, sidechain ducking, the Audio Mixer panel + project config, and audio import settings. Build & export: the Compress Audio package option.
1 parent 0ad7afb commit b30c8ba

8 files changed

Lines changed: 168 additions & 0 deletions

File tree

docs/astro/src/content/docs/guides/ai.mdx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ the agent entity (the same channel your code and the editor use):
107107
| `timeline.play` | action | Raise the agent's [`TimelinePlayer`](/docs/guides/timeline/) play flag. On a finished clip this replays it from the top. |
108108
| `timeline.pause` | action | Lower the play flag (resume with `timeline.play`). |
109109
| `timeline.finished` | condition | True once the clip has completed (a `once` clip that ran to its end) and is not playing. |
110+
| `spriteAnim.play` | action | Play the agent's sprite flipbook; the **argument** switches to that clip. |
111+
| `spriteAnim.restart` | action | Rewind the flipbook to frame 0 and play (argument switches clip). |
112+
| `spriteAnim.stop` | action | Pause the flipbook. |
113+
| `spriteAnim.finished` | condition | True once a one-shot sprite clip has finished. |
114+
115+
Actions can carry an optional **string argument** — set it next to the action
116+
name in the FSM state inspector (or on a BT action node). Built-ins use it for
117+
data the component can't carry per-state, like which clip `spriteAnim.play`
118+
should switch to; your own registered actions receive it as their third
119+
parameter: `(ctx, blackboard, arg) => …`.
110120

111121
Together they make a **code-free cutscene state**: entering the state starts the
112122
clip, and its completion drives the transition out.

docs/astro/src/content/docs/guides/animation.mdx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const setClip = defineSystem([Query(Mut(SpriteAnimator))], (q) => {
3838
| `playing` | boolean | `true` | Whether playback is advancing. |
3939
| `loop` | boolean | `true` | Loop the clip vs. hold the last frame. |
4040
| `enabled` | boolean | `true` | Disable to freeze the animator. |
41+
| `finished` | boolean | `false` | Read-only: latched when a one-shot clip completes. Raising `playing` on a finished animator replays from frame 0. |
4142
| `currentFrame` | number | `0` | Read-only: the frame index being shown. |
4243
| `frameTimer` | number | `0` | Read-only: time accumulated on the current frame. |
4344

@@ -65,6 +66,43 @@ const jump = defineSystem([Query(Mut(SpriteAnimator)), Res(SpriteAnimation)], (q
6566
Clips can carry **frame events** (`SpriteAnimEvent`) that fire when playback
6667
reaches a frame — use them for footstep sounds or hit frames.
6768

69+
### Authoring clips in the editor
70+
71+
Clips are `.esanim` assets you author visually — no JSON by hand:
72+
73+
1. **Right-click a texture** in the Content Browser and choose **Create Sprite
74+
Animation**. The Flipbook editor opens with the sheet under a slicing grid
75+
(the cell size is guessed from the image; adjust cell width/height, margin,
76+
and spacing in the toolbar).
77+
2. **Click or drag across cells** to append frames. The frame strip below shows
78+
each frame's thumbnail with an editable duration (ms; empty = `1000 / FPS`),
79+
drag to reorder, and a live looping preview.
80+
3. **Save**, then **right-click the `.esanim` → Create Animated Sprite** (or
81+
drag it into the viewport). You get a `Sprite` + `SpriteAnimator` entity
82+
posed at frame 0 — it plays in Play mode with zero code.
83+
84+
Selecting an animated sprite loops its flipbook **in the viewport while
85+
editing** (toggle with the Preview FX show flag). If the clip is open in the
86+
Flipbook editor at the same time, frame edits animate live as you make them.
87+
88+
Re-slicing the grid moves every frame consistently — frames reference grid
89+
cells, not pixel rectangles. Frames that fall outside the current grid are
90+
flagged red in the strip.
91+
92+
### Driving clips from a state machine — no code
93+
94+
The [FSM/BT built-ins](/docs/guides/ai/) drive flipbooks as data. An action's
95+
optional **argument** carries the clip, so idle/run/attack switching is pure
96+
`.esfsm` on the existing state-machine canvas:
97+
98+
| Name | Kind | Description |
99+
|---|---|---|
100+
| `spriteAnim.play` | action | Play. With a clip argument, switch to that clip (rewinds to frame 0). Safe on `onUpdate` — same-clip play while playing is a no-op. |
101+
| `spriteAnim.restart` | action | Unconditional rewind + play (re-trigger a one-shot mid-flight). |
102+
| `spriteAnim.stop` | action | Pause playback. |
103+
| `spriteAnim.finished` | condition | True once a one-shot clip completed — `onEnter: spriteAnim.play` + a `spriteAnim.finished` transition is a self-contained attack state. |
104+
105+
68106
## Tweens
69107

70108
The `Tween` resource interpolates a property from one value to another over a

docs/astro/src/content/docs/guides/audio.mdx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,46 @@ defaulting to `sfx`. Volume setters exist for `setMasterVolume` (a global slider
131131
and `setMusicVolume` / `setSFXVolume` / `setUIVolume`. The `voice` bus routes sounds
132132
but has no volume setter — toggle it with `muteBus('voice', …)`.
133133

134+
### Bus effects & ducking
135+
136+
Each bus carries a DSP insert chain, declared as data:
137+
138+
```typescript
139+
audio.setBusEffects('music', [
140+
{ type: 'filter', filter: 'lowpass', frequency: 800, q: 1 }, // muffle (pause menu)
141+
{ type: 'reverb', seconds: 1.5, wet: 0.3 }, // procedural room tail
142+
{ type: 'compressor', thresholdDb: -24, ratio: 4 },
143+
]);
144+
audio.setBusEffects('music', []); // clear
145+
```
146+
147+
Sidechain ducking is a rule, not code — duck music while voice lines play:
148+
149+
```typescript
150+
audio.setBusDucking('music', { trigger: 'voice', amount: 0.3, attack: 0.05, release: 0.4 });
151+
audio.setBusDucking('music', null); // remove
152+
```
153+
154+
While the `trigger` bus carries signal, the target's duck stage ramps to
155+
`amount`; on silence it releases back to 1. Ducking is a separate gain stage,
156+
so it never fights the user's volume setting. On backends without a WebAudio
157+
graph (WeChat) both APIs degrade to no-ops, like the volume calls.
158+
159+
### The Audio Mixer panel & project config
160+
161+
The **Audio Mixer** bottom-dock panel edits all of this visually — one strip
162+
per bus with a volume fader, mute, the effect chain, a duck-by rule, and
163+
custom buses. Edits persist to `project.esproject` (`features.audio`) and
164+
apply live in the editor; Play and every export boot the identical mix.
165+
166+
### Import settings & cooked audio
167+
168+
Selecting an audio asset shows a decoded waveform with play/seek plus **Import
169+
Settings**: `Compress` and `Bitrate` control the cook's WAV → MP3 transcode
170+
(enable **Compress audio** in the Package dialog). Already-compressed formats
171+
pass through untouched. MP3 has a small encoder delay — turn `Compress` off on
172+
clips that must loop seamlessly.
173+
134174
## Spatial audio
135175

136176
Set `AudioSource.spatial = true` and give your listener entity (usually the camera

docs/astro/src/content/docs/guides/build-export.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ module for each engine feature the game uses (`physics-wechat`, `spine-wechat`,
9999

100100
The Package dialog also drives what the **cook** does to your assets:
101101

102+
- **Compress audio** — re-encode WAV sources to MP3 at cook (per-asset Import
103+
Settings can opt a clip out or pick a bitrate; other audio formats pass
104+
through unchanged).
102105
- **Compress textures** — encode PNGs to GPU-ready **KTX2** (Basis Universal), which
103106
the runtime transcodes to the best format each device supports (ASTC → ETC2 → S3TC,
104107
falling back to RGBA8). Smaller downloads and less VRAM; leave off to ship raw PNGs.

docs/astro/src/content/docs/zh-cn/guides/ai.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ export enum Status { Success = 'success', Failure = 'failure', Running = 'runnin
9595
| `timeline.play` | 动作 | 拉起该实体 [`TimelinePlayer`](/docs/zh-cn/guides/timeline/) 的播放旗标。对已播完的片段,从头重播。 |
9696
| `timeline.pause` | 动作 | 放下播放旗标(用 `timeline.play` 恢复)。 |
9797
| `timeline.finished` | 条件 | 片段已完成(`once` 片段播到末尾)且未在播放时为真。 |
98+
| `spriteAnim.play` | 动作 | 播放代理实体的精灵翻页动画;**参数**可切换到指定剪辑。 |
99+
| `spriteAnim.restart` | 动作 | 回卷到第 0 帧并播放(参数可切换剪辑)。 |
100+
| `spriteAnim.stop` | 动作 | 暂停翻页动画。 |
101+
| `spriteAnim.finished` | 条件 | 一次性精灵剪辑播完后为真。 |
102+
103+
动作可携带一个可选**字符串参数**——在 FSM 状态检查器的动作名旁(或 BT 动作节点上)填写。
104+
内置动作用它承载组件无法按状态携带的数据,比如 `spriteAnim.play` 要切换到哪个剪辑;
105+
你自己注册的动作在第三个参数收到它:`(ctx, blackboard, arg) => …`
98106

99107
三者组合出一个**零代码的过场状态**:进入状态即播放片段,片段播完即驱动转移:
100108

docs/astro/src/content/docs/zh-cn/guides/animation.mdx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const setClip = defineSystem([Query(Mut(SpriteAnimator))], (q) => {
3737
| `playing` | boolean | `true` | 播放是否在推进。 |
3838
| `loop` | boolean | `true` | 循环片段 vs 停在最后一帧。 |
3939
| `enabled` | boolean | `true` | 关掉即冻结动画器。 |
40+
| `finished` | boolean | `false` | 只读:一次性片段播完时锁存。在 finished 状态抬起 `playing` 会从第 0 帧重播。 |
4041
| `currentFrame` | number | `0` | 只读:正在显示的帧索引。 |
4142
| `frameTimer` | number | `0` | 只读:当前帧已累积的时间。 |
4243

@@ -62,6 +63,36 @@ const jump = defineSystem([Query(Mut(SpriteAnimator)), Res(SpriteAnimation)], (q
6263

6364
片段可以携带**帧事件**(`SpriteAnimEvent`),播放到某帧时触发——用于脚步声或命中帧。
6465

66+
### 在编辑器中创作剪辑
67+
68+
剪辑是 `.esanim` 资产,全程可视化创作——不用手写 JSON:
69+
70+
1. 在内容浏览器中**右键纹理**,选择**创建精灵动画**。Flipbook 编辑器打开,
71+
精灵表上覆盖切片网格(格子尺寸按图片猜测;在工具栏调整格宽/格高/边距/间距)。
72+
2. **点击或拖选格子**追加帧。下方帧条显示每帧缩略图与可编辑时长
73+
(毫秒;留空 = `1000 / 帧率`),可拖拽重排,并带实时循环预览。
74+
3. **保存**,然后**右键 `.esanim` → 创建动画精灵**(或直接拖进视口)。
75+
得到一个定格在第 0 帧的 `Sprite` + `SpriteAnimator` 实体——进 Play 零代码播放。
76+
77+
选中动画精灵时,翻页动画**在编辑态视口中循环播放**(用 Preview FX 显示开关控制)。
78+
若该剪辑同时在 Flipbook 编辑器中打开,改帧即时反映在视口里。
79+
80+
重新切片时所有帧一致跟随——帧引用的是网格格子,不是像素矩形。
81+
超出当前网格的帧会在帧条中标红。
82+
83+
### 用状态机驱动剪辑——零代码
84+
85+
[FSM/BT 内置](/docs/zh-cn/guides/ai/)以数据驱动翻页动画。动作的可选**参数**
86+
携带剪辑,所以 idle/run/attack 切换是纯 `.esfsm` 数据,画在现有状态机画布上:
87+
88+
| 名称 | 类型 | 说明 |
89+
|---|---|---|
90+
| `spriteAnim.play` | 动作 | 播放。带剪辑参数时切换到该剪辑(回卷到第 0 帧)。可安全放在 `onUpdate`——同剪辑播放中为空操作。 |
91+
| `spriteAnim.restart` | 动作 | 无条件回卷 + 播放(中途重触发一次性动画)。 |
92+
| `spriteAnim.stop` | 动作 | 暂停播放。 |
93+
| `spriteAnim.finished` | 条件 | 一次性剪辑播完后为真——`onEnter: spriteAnim.play` + `spriteAnim.finished` 过渡即是自包含的攻击状态。 |
94+
95+
6596
## 补间(Tween)
6697

6798
`Tween` 资源在一段时长内把属性从一个值插值到另一个值。`to(entity, target, from, to,

docs/astro/src/content/docs/zh-cn/guides/audio.mdx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,42 @@ audio.muteBus('music', true);
124124
`setMasterVolume`(全局滑条)和 `setMusicVolume` / `setSFXVolume` / `setUIVolume``voice`
125125
总线能路由声音但没有音量设置器——用 `muteBus('voice', …)` 开关它。
126126

127+
### 总线效果与自动闪避(ducking)
128+
129+
每条总线携带一条 DSP 插入链,以数据声明:
130+
131+
```typescript
132+
audio.setBusEffects('music', [
133+
{ type: 'filter', filter: 'lowpass', frequency: 800, q: 1 }, // 闷化(暂停菜单)
134+
{ type: 'reverb', seconds: 1.5, wet: 0.3 }, // 程序化房间混响
135+
{ type: 'compressor', thresholdDb: -24, ratio: 4 },
136+
]);
137+
audio.setBusEffects('music', []); // 清空
138+
```
139+
140+
旁链闪避是一条规则,不是代码——语音播放时自动压低音乐:
141+
142+
```typescript
143+
audio.setBusDucking('music', { trigger: 'voice', amount: 0.3, attack: 0.05, release: 0.4 });
144+
audio.setBusDucking('music', null); // 移除
145+
```
146+
147+
`trigger` 总线有信号时,目标总线的闪避级压到 `amount`;静默后按 `release` 恢复到 1。
148+
闪避是独立的增益级,不会与用户音量设置打架。无 WebAudio 图的后端(微信)上,
149+
两个 API 与音量调用一样优雅降级为空操作。
150+
151+
### 音频混音器面板与项目配置
152+
153+
底部停靠的**音频混音器**面板可视化编辑以上一切——每总线一条 strip:音量推子、
154+
静音、效果链、闪避规则、自定义总线。编辑持久化到 `project.esproject`
155+
(`features.audio`)并在编辑器中即时生效;Play 与所有导出以同一套混音启动。
156+
157+
### 导入设置与打包音频
158+
159+
选中音频资产会显示解码波形(可播放/点击跳转)和**导入设置**:`Compress`
160+
`Bitrate` 控制打包时的 WAV → MP3 转码(在打包对话框勾选**压缩音频**)。
161+
已压缩格式原样通过。MP3 有少量编码器延迟——需要无缝循环的素材请关闭 `Compress`
162+
127163
## 空间音频
128164

129165
`AudioSource.spatial = true`,并给监听实体(通常是相机或玩家)加一个启用的 `AudioListener`

docs/astro/src/content/docs/zh-cn/guides/build-export.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ node build-tools/cli.js build -t playable
8585

8686
打包对话框还控制**烘焙**如何处理你的资产:
8787

88+
- **压缩音频** —— 打包时把 WAV 源重编码为 MP3(可在资产的导入设置中单独关闭或选码率;
89+
其他音频格式原样通过)。
8890
- **压缩纹理** —— 把 PNG 编码为 GPU 就绪的 **KTX2**(Basis Universal),运行时再转码为
8991
设备支持的最佳格式(ASTC → ETC2 → S3TC,最后回退 RGBA8)。下载更小、显存更省;关掉则
9092
发布原始 PNG。

0 commit comments

Comments
 (0)