Files
aibis-dream/Docs/帧动画角色配置指南(策划版).md
T

10 KiB
Raw Blame History

帧动画角色配置指南(策划版)

本文说明帧动画角色的 Flow 配置Yarn 调用。Clip 的切图、导入和帧时长配置不在本文展开。

示例资源:Assets/GameContent/Huoshan/Actor/火山Graph.asset

当前的 火山Graph 已有 Clip,但还没有配置 Flow。下文的 Flow 名称是教学示例,不代表资源中已经存在。

1. 先理解 Clip 和 Flow

  • Clip:一段独立帧动画,例如 摘帽扣头切屏特效伸手表情idle
  • Flow:把多个 Clip 按顺序串成一次完整表演,例如 摘帽 → 伸手表情idle
  • Yarn 调用时,Clip ID 和 Flow ID 的写法完全相同,系统会自动查找对应内容。

适合直接调用 Clip 的情况:只播放一个动作或切换一个循环表情。

适合配置 Flow 的情况:动作需要连续播放多个阶段,并且希望 Yarn 只写一条命令。

2. 打开火山 Graph

  1. 在 Project 窗口选中 Assets/GameContent/Huoshan/Actor/火山Graph.asset
  2. 点击 Inspector 中的 Open Frame Animation Graph Editor
  3. 也可以从 Unity 菜单打开:Window > Aibis Dream > Frame Animation Graph Editor,再选择 火山Graph

编辑器左侧是 Clip / Flow 列表,中间是节点画布,右侧是当前选中内容的属性。

3. 配置一个 Flow

下面以新建 摘帽到伸手_Flow 为例,预期顺序为:

摘帽 → 伸手表情idle(循环)

第一步:把 Clip 放到画布

  1. 在左侧选择 Clips
  2. 摘帽 从左侧拖到中间画布,生成一个 Node。
  3. 再把 伸手表情idle 拖到画布,生成第二个 Node。

同一个 Clip 可以在画布中生成多个 Node。Node 只是 Flow 中对 Clip 的一次引用,不会复制或修改原 Clip。

第二步:连接播放顺序

摘帽 Node 右侧的输出点拖线,连接到 伸手表情idle Node 左侧的输入点。

当前 Flow 只支持单线顺序播放:

  • 一个 Node 最多只能连接一个后继 Node;
  • 不支持分支;
  • 不支持把路径连成环;
  • 播放顺序由连线决定,不由节点在画布上的左右位置决定。

第三步:创建 Flow 并指定入口

  1. 选中 摘帽 Node。
  2. 右键该 Node,选择 Create Flow From Node;也可用画布上方 Canvas > Create Flow From Selection
  3. 将 Flow ID 填为 摘帽到伸手_Flow
  4. 确认入口是 摘帽 Node。入口 Node 会显示 E 标记。

Flow ID 就是 Yarn 中填写的动画名。建议使用有明确含义且不易重复的名称,例如 摘帽到伸手_Flow

Clip ID 和 Flow ID 共用同一套命名空间,不能重名。修改 ID 后,已有 Yarn 文本不会自动更新,必须同步搜索并修改调用。

第四步:设置结尾行为

选中最后一个 Node,在右侧设置 Override End Behavior。常用选项:

选项 播放结束后的表现 常见用途
Loop 从头循环最后一个 Clip idle、持续表情
HoldLastFrame 停在最后一帧 一次动作的定格结尾
Clear 清空当前 Sprite 动画结束后不显示图片
HideTarget 隐藏渲染目标 动画结束后隐藏角色

本例最后的 伸手表情idle 应使用 Loop

注意:只有终点 Node 才能设置结束行为。一个 Node 如果设置了结束行为,就不能再连接后继 Node。中间 Node 播完后会自动进入下一个 Node,不需要设置结束行为。

如需单独调整某个 Node 的速度,可勾选 Override Speed1 为原速,2 为两倍速,0.5 为半速。速度必须大于 0

第五步:预览、校验和保存

  1. 在左侧选择刚创建的 Flow,点击右侧 Focus Flow On Canvas
  2. 使用预览区的播放按钮检查顺序和循环结果。
  3. 点击顶部 Validate,底部 Validation 中不能有 Error。
  4. 点击顶部 Save 保存。

4. Yarn 调用

初始化角色

帧动画角色首次出现时,先初始化:

<<init_actor 火山 clinic FrameAnimation>>

参数依次为:

角色名  槽位名  角色类型

火山 会加载 Addressable 地址为 FrameAnimation/火山 的 Graph。init_actor 会等待角色 Prefab 和 Graph 加载完成,因此下一行可以直接切动画。

同一段角色出场流程中只需初始化一次,不要在每次换动画前重复初始化。

初始化完成后不会自动播放 Graph 中的 Default Playable,需要再调用一次 Clip 或 Flow。

调用一个 Clip

Clip ID 直接写在命令的第一个参数中:

<<change_actor_state 捂头表情idle 火山>>

这条命令会直接播放 火山Graph 中的 捂头表情idle Clip。Clip 播完后的表现由该 Clip 的 End Behavior 决定:

  • Loop:持续循环,直到被下一次状态切换替换;
  • HoldLastFrame:播放一次并停在最后一帧;
  • Clear:播放一次后清空图片;
  • HideTarget:播放一次后隐藏角色渲染目标。

Clip:播放后立刻继续 Yarn

<<change_actor_state "伸手 石化表情" 火山>>
hs: 我太伤心了。

change_actor_state 只负责开始播放,Yarn 不会等 Clip 播完,会立即执行下一行。适用于:

  • 切换 idle 或持续循环表情;
  • Clip 需要和对白同时播放;
  • 后续时机由策划自己用 wait 控制。

Clip:播放完成后再继续 Yarn

<<change_actor_state_async 扣头切屏特效 火山>>
<<change_actor_state 扣头表情idle 火山>>

change_actor_state_async 会等待 Clip

  • 非循环 Clip:等待整段播放结束;
  • Loop Clip:等待第一轮播放结束,然后继续执行 Yarn;动画本身仍会循环。

因此,一次性动作之后要准确切换 idle 时,推荐使用上面的“异步动作 Clip → 循环 idle Clip”写法,不需要猜测 wait 秒数。

调用一个 Flow

Flow 的调用格式与 Clip 完全相同,只需把第一个参数换成 Flow ID。例如已配置 摘帽到伸手_Flow

Flow:播放后立刻继续 Yarn

<<change_actor_state 摘帽到伸手_Flow 火山>>
hs: 戴上“实实”牌帽子,给你的头顶添件宝!

Yarn 会立即继续对白,Flow 则在后台按照连线依次播放。适合整段表演与对白同时发生的情况。

Flow:播放到终点首轮后再继续 Yarn

<<change_actor_state_async 摘帽到伸手_Flow 火山>>
// Flow 的前置动作和终点 Loop 首轮播放完后,才执行这里

change_actor_state_async 会从入口开始等待整条 Flow

  • 终点为非循环 Clip:等待所有节点自然播放结束;
  • 前置动作 → 终点 Loop 的 Flow:等待前置动作和终点 Loop 的第一轮全部结束。

如果终点是 Loop,命令返回后终点 Clip 仍会继续循环,直到被下一次状态切换替换。

快速选择命令

要播放的内容 希望 Yarn 是否等待 写法
单个 Clip 不等待 <<change_actor_state ClipID 角色名>>
单个 Clip 等完整动画;Loop 等第一轮 <<change_actor_state_async ClipID 角色名>>
一整条 Flow 不等待 <<change_actor_state FlowID 角色名>>
一整条 Flow 等到终点首轮完成 <<change_actor_state_async FlowID 角色名>>

命令本身不需要标明目标是 Clip 还是 Flow。系统会用 ID 在当前角色的 Graph 中查找;因此 Clip ID 和 Flow ID 不能重名。

名称中有空格时

Clip ID、Flow ID、角色名或槽位名中包含空格时,必须加英文双引号:

<<change_actor_state "伸手 石化表情" 火山>>
<<change_actor_state_async "摘帽 到 伸手_Flow" 火山>>

不含空格时可以不加;为减少出错,也可以统一加英文双引号。

5. 火山的完整示例

下面同时演示 Clip 和 Flow 调用,并假设已按前文创建 摘帽到伸手_Flow

<<init_actor 火山 clinic FrameAnimation>>

// 调用 Loop Clip:立即继续 Yarnidle 在对白期间持续循环
<<change_actor_state 捂头表情idle 火山>>
<<fade_in_actor 火山>>

hs: 医——生——救——我——!

// 调用 Flow:等“摘帽”播完,再等终点“伸手表情idle”完成第一轮
<<change_actor_state_async 摘帽到伸手_Flow 火山>>

// Flow 返回后,终点的伸手 idle 仍在循环
hs: 戴上“实实”牌帽子,给你的头顶添件宝!

// 调用一次性 Clip,并等待它完整播完
<<change_actor_state_async "扣头切屏特效" 火山>>

// 再调用另一个 Loop Clip,替换当前状态并继续对白
<<change_actor_state "扣头表情idle" 火山>>
hs: 我……没有活干了。

6. 提交前检查

  • Flow 的入口是否是第一个动作,而不是终点 idle?
  • 节点是否按预期连线,且没有分支或环?
  • 只有最后一个 Node 设置了结束行为吗?
  • 需要持续显示的 idle 是否设置为 Loop
  • Flow ID 是否与已有 Clip / Flow 重名?
  • Yarn 中的 ID 与 Graph 完全一致,包括空格和大小写吗?
  • 需要等动画时是否用了 change_actor_state_async
  • 顶部 Validate 是否无 Error
  • 是否点击 Save

7. 常见问题

调用后没有动画

先检查角色是否用 FrameAnimation 类型初始化,再检查 Graph 的 Addressable 地址是否为 FrameAnimation/角色名。火山应为 FrameAnimation/火山

提示 playable 找不到

Yarn 中传入的是 Clip ID 或 Flow ID,不是资源文件名、Graph 名或 Node 的 Display Name。检查字符、空格和大小写是否完全一致。

动画刚开始就被打断

后面很可能紧跟了另一条 change_actor_state。普通命令不会等待;需要等当前动画完成时改用 change_actor_state_async

循环动画导致剧情无法继续

使用 change_actor_state_async 等待 Loop 时,只会等待第一轮,不会无限阻塞。如果仍未继续,先运行 Validate 检查 Flow 路径和结尾配置。

想让 Flow 中途停住

当前 Flow 是顺序播放,不支持分支或中途等待 Yarn。应拆成两个 Clip / Flow,在 Yarn 中分两次调用。