# 帧动画系统第四阶段手动测试 ## 1. 测试目标 验证第四阶段新增的节点画布、顺序连线、Flow 编排、选择定位、删除影响分析、自动布局和状态恢复。导入刷新可按第一、二阶段文档做回归;动画预览、时间轴和逐帧播放不属于本阶段。 ## 2. 测试准备 1. 备份或提交当前工作区改动。 2. 在 Unity 中等待脚本编译完成,确认 Console 没有编译错误。 3. 如需标准样例,执行 `Tools > Frame Animation > Upgrade Phase 4 Sample (Non-Destructive)`。 4. 打开 `Assets/GameContent/Test/FrameAnimation/Import/ImportSampleGraph.asset`。 5. 点击 Inspector 中的 `Open Graph Editor`,或使用 `Window > Aibis Dream > Frame Animation Graph Editor`。 样例升级是幂等、非重建操作:它只补充固定 ID 的三个 Node、两条 Edge、两个 Flow 及其 EditorData;不会删除或重建 Graph,不会移除已有来源或 Clip。重复执行后数量不应继续增加。 ## 3. 基础画布 ### 3.1 打开与导航 1. 用鼠标滚轮缩放画布。 2. 按住中键拖动画布。 3. 拖出矩形框选多个节点。 4. 点击 `Frame Selection`。 预期:缩放、平移、框选正常;`Frame Selection` 将选中元素完整放入视野;多选时右侧显示数量摘要,不提供批量属性编辑。 ### 3.2 已有数据加载 检查样例中的 `待机 Node`、`眨眼 Node` 和 `Shared Idle Node`,以及两条指向共享节点的 Edge。 预期:节点位置稳定;共享节点显示多个 Flow 标记;`Shared Idle Node` 显示 Loop 结束行为且输出端不可连接;打开窗口本身不会新增 Node 或 Edge。 ## 4. Node 创建与编辑 ### 4.1 从 Clip 列表拖入 1. 在左侧选择 `Clips`。 2. 将同一个 Clip 分别拖到画布两个不同位置。 预期:创建两个不同 internalId 的 Node,二者引用同一 Clip;释放位置被保存;Undo 一次只撤销最近创建的一个 Node。 ### 4.2 右键创建 1. 在画布空白处右键,选择 `Create Clip Node`。 2. 在搜索框查找一个 Clip 并创建。 预期:节点出现在右键位置;displayName 默认取 Clip displayName,空时取 Clip id。 ### 4.3 属性编辑 选中 Node,在右侧依次测试: - 修改 displayName。 - 从 Clip 下拉切换引用。 - 开启速度覆盖并输入 `0`、正数、负数。 - 开启和关闭结束行为覆盖。 - 复制 internalId。 预期:修改立即反映到画布;速度 `0` 被保留,负数被保留并产生可定位校验错误;失效 Clip 显示 `` 并可通过下拉修复;普通属性编辑支持 Undo/Redo。 ## 5. Edge 连接约束 分别尝试以下操作: 1. 从无后继、无结束覆盖的 Node 连接到另一个 Node。 2. 再从同一起点连接第二个后继。 3. 节点连接自身。 4. 连接一条会形成多节点环路的 Edge。 5. 从设置了结束行为覆盖的 Node 拉出连接。 预期:第 1 项成功,Edge 固定为 `default / Always`;第 2~5 项被阻止并显示明确原因,Graph 数据不变化。 选中已有后继的 Node,再开启结束行为覆盖。 预期:出现“删除 Edge 并应用”确认;确认后 Edge 与结束行为在同一个 Undo 事务内变化;取消则两者都不变化。 ## 6. Flow 创建与入口 ### 6.1 创建 Flow 1. 只选中一个非 Flow 入口 Node。 2. 点击画布工具栏 `Create Flow`,或节点右键 `Create Flow From Node`。 3. 保持默认 id 创建。 预期:默认 id 为“节点显示名 + Flow”;冲突时追加 `2`、`3`;Clip/Flow 同名会阻止创建;已作为其他 Flow 入口的 Node 会阻止创建。 ### 6.2 修改入口 1. 左侧选择一个 Flow。 2. 在画布选择目标 Node。 3. 回到 Flow 属性,点击 `Set Selected Node As Entry`。 预期:入口只通过该命令修改;目标已是其他 Flow 入口时阻止修改;成功后 Flow 聚焦和可达范围立即更新。 ### 6.3 聚焦与共享节点 1. 从左侧或 Flow 下拉分别选择两个样例 Flow。 2. 检查工具栏显示 `Focused: ` 和 `Exit Focus`,点击 `Frame Flow`。 3. 选择当前 Flow 内的 Node/Edge,再选择当前 Flow 外的 Node/Edge。 4. 重新进入聚焦后,从 Flows 页切换到 Clips 或 Sources 页。 5. 重新进入聚焦后,成功拖入或右键创建一个 Node。 6. 分别使用 `Exit Focus`、`Show All`、下拉框 `Show All` 和画布获得焦点后的 `Esc` 退出。 预期:聚焦时仍保留全部节点和 Edge,只适度降低无关元素透明度;共享节点在两个 Flow 中均正常高亮;Flow 内选择保持聚焦,范围外选择、离开 Flows 资源上下文和成功创建 Node 自动退出;四种主动退出方式都恢复全部亮度,其中 `Show All` 还会框住全部元素。 ## 7. 选择与问题定位 1. 从 Clip 行执行“定位引用”。 2. 点击左侧 Flow。 3. 执行 `Validate`,点击一个 Node 或 Edge 问题。 4. 在聚焦某 Flow 时,定位一个不属于该 Flow 的问题。 预期:左侧资源、画布和右侧属性同步;Node/Edge 被框入视野;目标不属于当前 Flow 时自动切换 `Show All`,不会仅以弱化状态显示。 ## 8. 删除与影响分析 ### 8.1 删除 Edge 选择一个处于 Flow 可达路径中的 Edge,按 Delete 或点击属性区 `Disconnect Edge`。 预期:确认框列出受影响 Flow 和失去可达关系的 Node 数;取消不修改;确认只删除 Edge,不删除 Node 或 Flow。 ### 8.2 删除普通 Node 删除一个非入口但位于 Flow 路径中的 Node。 预期:确认框列出受影响 Flow;确认后自动删除该 Node 的全部入边、出边和 NodeEditorData,但不删除引用的 Clip。 ### 8.3 删除入口 Node 删除一个或多个 Flow 的入口 Node。 预期:只提供“同时删除这些 Flow”或取消;确认后 Node、关联 Edge、入口 Flow 及相应 EditorData 在同一 Undo 事务内删除。 ### 8.4 批量删除 框选多个相连 Node 后按 Delete。 预期:只出现一次综合确认;关联 Edge 去重,不发生重复删除或异常。 ## 9. 位置与自动布局 1. 拖动一个 Node,关闭并重新打开窗口。 2. 选中两个以上 Node,点击 `Auto Layout`。 3. 取消选择、聚焦一个 Flow,再点击 `Auto Layout`。 4. `Show All` 后再次自动布局。 预期:拖动位置被保存且可 Undo;三种布局范围依次为选中集合、当前 Flow 可达节点、全部节点;布局从左到右,同层排序稳定;范围外 Node 不移动;一次布局只产生一个 Undo。 ## 10. Undo、保存与状态恢复 1. 依次执行创建 Node、移动、连线、创建 Flow、改入口和删除。 2. 连续 Undo,再连续 Redo。 3. 点击 `Save`,关闭窗口并重新打开。 4. 触发脚本重新编译或 Domain Reload。 预期:每个具名事务完整恢复;不会出现只有画布变化而数据未恢复的情况;internalId、Edge、Flow 入口和节点位置稳定;同一窗口会话内的有效 Flow 聚焦在 Undo/Redo 后重新计算,失效聚焦自动退出;窗口重开或 Domain Reload 后始终为 `Show All`,不会恢复旧聚焦。 ## 11. 综合校验 点击 `Validate`,检查以下类型能够显示并定位: - 缺失或重复 Node/Edge ID、无效引用、多后继、自连接、环路。 - 终点结束覆盖与后继冲突。 - 缺失 NodeEditorData / FlowEditorData。 - 孤立或重复 EditorData。 - 第一至第三阶段已有的 Clip、Flow、ImportSource 和资产所有权问题。 预期:轻量编辑只触发结构校验;JSON、Texture、Sprite 和 hash 只在 `Validate`、`Preview` 或 `Refresh` 时检查。 ## 12. 回归检查 1. Preview / Refresh 一个 ImportSource,确认画布引用保持。 2. 重命名 Clip,确认所有 Node.clipId 同步迁移。 3. 重命名 Flow,确认 FlowEditorData 和默认 playable 同步迁移。 4. 尝试删除仍被 Node 引用的 Clip。 5. 进入第一阶段运行时样例场景,验证直接 Clip 和 Flow 播放。 预期:导入刷新不重建已有 Clip sub-asset;重命名引用原子迁移;被 Node 引用的 Clip 仍受删除保护;运行时行为与前三阶段一致。 ## 13. 通过标准 - 无 Unity 编译错误或未处理异常。 - 所有非法新连接和入口冲突均在写入前阻止。 - 所有确认取消操作保持 Graph 不变。 - Node、Edge、Flow、EditorData 的 Undo/Redo 和重载后状态一致。 - 样例升级重复执行不增加重复 Node、Edge 或 Flow,且既有 ImportSource(包括用户添加来源)保持不变。 - 第一至第三阶段自动测试和 PlayMode 测试无回归。