713 lines
22 KiB
Markdown
713 lines
22 KiB
Markdown
# SpineParticle · Spine JSON 导出设计标准规范
|
||
|
||
> 文档性质:导出功能开发、验收与后续维护的唯一对齐基线
|
||
> 规范状态:已完成产品规则对齐,导出设置面板已实现,JSON 导出逻辑尚未开始
|
||
> 目标格式:Spine JSON 4.2
|
||
> 主要用途:将导出 JSON 重新导入 Spine 编辑器继续编辑
|
||
> 最后更新:2026-08-31
|
||
|
||
---
|
||
|
||
## 一、规范目的
|
||
|
||
本规范用于固定 SpineParticle 的 Spine JSON 导出范围、骨架结构、动画烘焙、资源引用、拖尾蒙皮、关键帧压缩和导出设置语义,避免后续开发因上下文丢失或实现人员变化而偏离已确认规则。
|
||
|
||
后续实现若与本文冲突,应先重新确认并更新本文,不能仅在代码中改变既定语义。
|
||
|
||
---
|
||
|
||
## 二、导出目标与边界
|
||
|
||
### 2.1 导出目标
|
||
|
||
导出结果是一个能够由 Spine 4.2 识别,并能重新导入 Spine 编辑器继续编辑的 JSON 骨架动画文件。
|
||
|
||
导出数据必须满足:
|
||
|
||
1. 粒子表现不依赖 SpineParticle 编辑器运行时;
|
||
2. 粒子、序列帧、颜色、透明度、缩放、旋转、拖尾等表现被转换为 Spine 原生骨骼、插槽、附件与动画时间轴;
|
||
3. 与其他场景模块发生关联的粒子表现必须烘焙为独立动画数据;
|
||
4. 文件结构优先兼顾可编辑性、动画精度和合理体积;
|
||
5. 导出后使用 Spine 4.2 Runtime 进行结构解析验证。
|
||
|
||
### 2.2 导出内容
|
||
|
||
只导出场景中的粒子系统相关内容:
|
||
|
||
- 粒子系统骨骼;
|
||
- 粒子图片插槽和 Region 附件;
|
||
- 粒子位移、旋转、缩放动画;
|
||
- 粒子颜色和透明度动画;
|
||
- 粒子图片与序列帧附件切换;
|
||
- 拖尾骨骼链;
|
||
- 拖尾加权 Mesh、颜色、透明度和资源切换;
|
||
- 项目中的“所属动画”及其粒子时间轴。
|
||
|
||
### 2.3 不导出的内容
|
||
|
||
以下场景对象本身不进入 JSON:
|
||
|
||
- 碰撞体;
|
||
- 路径;
|
||
- 已加载的 Spine 对象;
|
||
- 原 Spine 对象中的骨骼、插槽、皮肤、图片和动画;
|
||
- 编辑器辅助线、网格、背景图、骨骼预览点和调试显示。
|
||
|
||
这些模块若影响了粒子运动,必须只烘焙其最终结果,不能在导出 JSON 中保留对原对象的引用。
|
||
|
||
### 2.4 场景显隐规则
|
||
|
||
- 场景对象小眼睛关闭的粒子系统不导出;
|
||
- 显示状态正常的粒子系统参与导出;
|
||
- 碰撞、路径和 Spine 对象无论是否显示都不作为对象导出;
|
||
- 若可见粒子系统的模拟依赖有效的碰撞、路径或 Spine 跟随,其最终影响仍应被烘焙。
|
||
|
||
---
|
||
|
||
## 三、格式依据与版本规则
|
||
|
||
### 3.1 格式依据
|
||
|
||
实现时依次以以下内容作为格式依据:
|
||
|
||
1. Spine 官方 GitHub 仓库中的 Spine 4.2 JSON 示例;
|
||
2. 项目当前使用的 `@esotericsoftware/spine-core 4.2.119` JSON 解析器;
|
||
3. 项目已有的 Spine 4.2 官方导出样本;
|
||
4. Spine 官方 JSON 格式说明。
|
||
|
||
官方中文说明中的部分示例仍使用 Spine 3.8,不能直接照搬旧版字段。实现必须重点核对 Spine 4.2 的:
|
||
|
||
- `skins` 结构;
|
||
- `rgba` 插槽时间轴;
|
||
- `attachments` 动画结构;
|
||
- 加权 Mesh 顶点编码;
|
||
- 附件切换;
|
||
- 多动画结构;
|
||
- Draw Order 字段命名;
|
||
- Sequence 附件及时间轴结构。
|
||
|
||
### 3.2 版本范围
|
||
|
||
第一版只支持:
|
||
|
||
```text
|
||
Spine 4.2
|
||
```
|
||
|
||
设置面板保留下拉框,以便以后扩展版本,但第一版不得提供没有真实兼容实现的 4.0、4.1 或其他版本选项。
|
||
|
||
---
|
||
|
||
## 四、整体 JSON 结构
|
||
|
||
导出 JSON 的主要结构为:
|
||
|
||
```text
|
||
skeleton
|
||
bones
|
||
slots
|
||
skins
|
||
animations
|
||
```
|
||
|
||
不输出无关约束、碰撞体或路径附件。
|
||
|
||
推荐骨架层级:
|
||
|
||
```text
|
||
root
|
||
├─ ParticleSystem1
|
||
│ ├─ _particle_000
|
||
│ ├─ _particle_001
|
||
│ ├─ _particle_000_trail_1_0
|
||
│ │ └─ _particle_000_trail_1_1
|
||
│ │ └─ ...
|
||
│ └─ ...
|
||
└─ ...
|
||
```
|
||
|
||
每个粒子系统必须作为 `root` 下的独立父骨骼,粒子骨骼统一使用简洁的 `_particle_000` 样式并归入对应系统。所有骨骼、插槽和附件名称仍须全局唯一;多系统发生重名时只为后续同名骨骼追加最短编号后缀。
|
||
|
||
---
|
||
|
||
## 五、Setup Pose 标准
|
||
|
||
### 5.1 普通骨骼
|
||
|
||
除拖尾子骨骼链外,所有导出骨骼的 Setup Pose 使用统一默认值:
|
||
|
||
```text
|
||
x = 0
|
||
y = 0
|
||
rotation = 0
|
||
scaleX = 1
|
||
scaleY = 1
|
||
```
|
||
|
||
粒子系统在编辑器中的位置、旋转和缩放不写入普通骨骼 Setup Pose,必须进入对应动画时间轴。
|
||
|
||
### 5.2 拖尾骨骼链例外
|
||
|
||
拖尾是加权 Mesh 的绑定骨骼链。为了保证导入 Spine 后初始蒙皮结构正确:
|
||
|
||
- 拖尾链保持正常父子层级;
|
||
- 子骨骼保留合理的绑定位置和骨骼长度;
|
||
- 子骨骼不能全部重叠在原点;
|
||
- 动画帧中的拖尾世界状态转换为相对父骨骼的局部位移和局部旋转;
|
||
- 拖尾链根独立于粒子图片骨骼的旋转和缩放,避免粒子图片变换意外污染拖尾蒙皮。
|
||
|
||
### 5.3 Setup Pose 可见性
|
||
|
||
所有蒙皮绑定完成后的粒子 Region 和拖尾 Mesh 在 Setup Pose 中默认透明度为 0,避免导入 Spine 后干扰已有图像显示。
|
||
|
||
动画开始后,由附件切换和 `rgba` 时间轴恢复正确图片、颜色与透明度。
|
||
|
||
---
|
||
|
||
## 六、粒子到 Spine 数据的映射
|
||
|
||
| SpineParticle 数据 | Spine 4.2 数据 |
|
||
|---|---|
|
||
| 粒子系统 | 系统根骨骼 |
|
||
| 粒子池槽位或独立出生粒子 | 粒子骨骼 |
|
||
| 粒子图片 | Region 附件 |
|
||
| 粒子图片显示层 | Slot |
|
||
| 粒子位置 | Bone Translate Timeline |
|
||
| 粒子旋转 | Bone Rotate Timeline |
|
||
| 粒子缩放 | Bone Scale Timeline |
|
||
| 粒子颜色与透明度 | Slot RGBA Timeline |
|
||
| 粒子出生、死亡、假死 | Attachment 与 RGBA Timeline |
|
||
| 多图片资源 | 同一 Slot 下的多个 Region 附件 |
|
||
| 序列帧 | Attachment Timeline 切换 Region |
|
||
| 混合模式 | Slot Blend |
|
||
| 拖尾 | 加权 Mesh + 拖尾骨骼链 |
|
||
| 拖尾颜色与透明度 | 拖尾 Slot RGBA Timeline |
|
||
| 所属动画 | `animations` 下的动画名称 |
|
||
|
||
---
|
||
|
||
## 七、粒子骨骼与对象池
|
||
|
||
### 7.1 开启骨骼对象池
|
||
|
||
开启时:
|
||
|
||
- 按粒子系统最大同时存活数量建立固定粒子骨骼池;
|
||
- 粒子死亡后骨骼可供后续粒子复用;
|
||
- 图片 Slot 和对应拖尾骨骼链随粒子骨骼一起复用;
|
||
- 文件骨骼数量和时间轴体积应显著小于不复用模式;
|
||
- 复用前后通过 Attachment 和 RGBA 关键帧明确隐藏、显示及切换资源。
|
||
|
||
### 7.2 关闭骨骼对象池
|
||
|
||
关闭时:
|
||
|
||
- 每一次逻辑粒子出生建立独立骨骼;
|
||
- 已死亡粒子的骨骼不再分配给后续粒子;
|
||
- 动画较长或发射率较高时允许产生大量骨骼;
|
||
- 界面无需阻止,但导出前可以提示预计骨骼数量和文件体积。
|
||
|
||
### 7.3 循环动画例外
|
||
|
||
纯循环持续动画必须保证循环衔接帧两端的粒子身份稳定。即使关闭对象池,也必须为跨越循环接缝的粒子维持稳定骨骼映射,避免循环首尾出现身份跳变。
|
||
|
||
---
|
||
|
||
## 八、图片与序列帧
|
||
|
||
### 8.1 图片文件
|
||
|
||
导出功能不复制、不下载、不嵌入 PNG,也不生成 Atlas。
|
||
|
||
JSON 只负责输出正确的图片资源路径。用户将在 Spine 中重新扫描并指定图片文件夹。
|
||
|
||
禁止把以下编辑器内部地址写入附件路径:
|
||
|
||
- Data URL;
|
||
- Blob URL;
|
||
- 浏览器临时对象地址;
|
||
- 本机绝对文件路径。
|
||
|
||
### 8.2 图片路径
|
||
|
||
设置中的图片路径,例如:
|
||
|
||
```text
|
||
./images/
|
||
```
|
||
|
||
写入 `skeleton.images`。
|
||
|
||
附件 `path` 只写相对于图片文件夹的资源路径,不重复附加 `./images/`。附件路径应:
|
||
|
||
- 保留资源子文件夹结构;
|
||
- 统一使用 `/`;
|
||
- 清理重复的 `./`;
|
||
- 使用稳定文件名;
|
||
- 默认使用不含图片扩展名的 Spine 资源路径;
|
||
- 检测并提示重复路径。
|
||
|
||
### 8.3 图片缺失
|
||
|
||
图片缺失不阻止导出。
|
||
|
||
- 仍然输出对应 Region 或 Mesh 附件;
|
||
- 保留用户可识别的文件名和路径;
|
||
- Spine 中允许显示缺失图片,用户可根据文件名补充文件;
|
||
- 能取得图片原始尺寸时写入真实尺寸;
|
||
- 完全无法取得尺寸时写入安全占位尺寸并给出提示;
|
||
- 缺图、路径重复或占位尺寸属于警告,不直接取消 JSON 下载。
|
||
|
||
### 8.4 图片尺寸、缩放和锚点
|
||
|
||
- Region `width/height` 使用图片原始像素尺寸;
|
||
- 粒子资源缩放已经体现在粒子骨骼 Scale 动画中,不得重复乘到图片尺寸;
|
||
- Pixi 锚点转换为 Region 相对骨骼中心的偏移;
|
||
- 转换时必须处理 Spine 数学坐标 Y 向上与 Pixi 屏幕坐标 Y 向下的差异;
|
||
- 实现后必须使用非中心锚点和旋转状态进行视觉对照。
|
||
|
||
### 8.5 序列帧
|
||
|
||
一组序列帧始终只使用一根粒子骨骼,不因图片数量增加骨骼。
|
||
|
||
第一版不依赖 Spine 原生 Sequence 命名约束,而采用:
|
||
|
||
- 每张序列图片建立独立 Region 附件;
|
||
- 使用 Attachment Timeline 切换当前 Region;
|
||
- 按烘焙后的最终图片索引输出,不在导出端重新推演播放模式。
|
||
|
||
需要完整支持:
|
||
|
||
- 单次-尾帧消失;
|
||
- 单次-尾帧固定;
|
||
- 正向循环;
|
||
- 反向循环。
|
||
|
||
---
|
||
|
||
## 九、拖尾加权 Mesh 标准
|
||
|
||
### 9.1 禁止项
|
||
|
||
拖尾不得使用逐帧 `attachments → deform` 时间轴作为正式导出方案。
|
||
|
||
### 9.2 正式结构
|
||
|
||
拖尾直接转换为:
|
||
|
||
```text
|
||
拖尾骨骼链 + 加权 Mesh + 骨骼动画
|
||
```
|
||
|
||
复用项目现有拖尾数据:
|
||
|
||
- `trailGridRows / trailGridCols` 生成网格拓扑;
|
||
- 当前三角形索引写入 `triangles`;
|
||
- 当前 UV 与图片旋转写入 `uvs`;
|
||
- `trailSkinWeights` 中的 `boneA / boneB / weight` 转换为 Spine 加权 Mesh 顶点编码;
|
||
- `trailState.bones` 转换为拖尾骨骼链动画;
|
||
- 拖尾资源切换使用同一拖尾 Slot 下的多个 Mesh 附件和 Attachment Timeline;
|
||
- 拖尾颜色和透明度使用拖尾 Slot 的 RGBA Timeline。
|
||
|
||
### 9.3 拖尾动画映射
|
||
|
||
- 拖尾长度由骨骼链各节点位置体现;
|
||
- 拖尾方向由骨骼旋转体现;
|
||
- 拖尾宽度由骨骼垂直缩放体现;
|
||
- 拖尾形状曲线进入 Mesh 的绑定顶点分布;
|
||
- 拖尾图片旋转进入 UV;
|
||
- 拖尾头部必须与粒子最终渲染位置一致;
|
||
- 每帧世界状态转换为父子骨骼局部状态后再写入时间轴。
|
||
|
||
### 9.4 权重标准
|
||
|
||
- 每个顶点使用项目已有的相邻骨骼影响关系;
|
||
- 每个顶点权重和必须在允许误差内等于 1;
|
||
- 骨骼索引必须对应最终 `bones` 数组顺序;
|
||
- 不允许引用不存在或被排除的骨骼;
|
||
- 导出后需要检查弯曲、宽度变化、资源旋转和粒子旋转情况下的拖尾形态。
|
||
|
||
---
|
||
|
||
## 十、外部关联烘焙
|
||
|
||
### 10.1 通用规则
|
||
|
||
所有导出动画先执行一次独立、确定性的离线烘焙:
|
||
|
||
1. 使用当前粒子系统随机种子重置模拟;
|
||
2. 按导出 FPS 逐帧推进;
|
||
3. 计算路径跟随、Spine 骨骼跟随、碰撞和全部修改器;
|
||
4. 记录粒子和拖尾最终渲染状态;
|
||
5. 将外部对象影响转换为系统根或粒子骨骼动画;
|
||
6. JSON 中不保留任何外部对象引用。
|
||
|
||
### 10.2 碰撞
|
||
|
||
- 不导出碰撞体;
|
||
- 碰撞造成的位置、速度方向、暂停、销毁和反弹结果进入最终粒子动画;
|
||
- 碰撞突变前后必须保留关键帧,不能跨越突变进行平滑压缩。
|
||
|
||
### 10.3 路径跟随
|
||
|
||
- 不导出路径对象或 Path Constraint;
|
||
- 本地空间跟随烘焙为系统根运动与粒子局部运动;
|
||
- 世界空间跟随烘焙为粒子最终世界运动,已出生粒子不能错误继承后续路径移动;
|
||
- 路径方向和旋转表现按画布最终结果写入。
|
||
|
||
### 10.4 Spine 骨骼跟随
|
||
|
||
- 不导出原 Spine 对象或原目标骨骼;
|
||
- 跟随位置和用户设置的偏移进入最终动画;
|
||
- 不额外继承原 Spine 骨骼的缩放和旋转,保持编辑器现有语义;
|
||
- 目标失效时按编辑器当前默认回退逻辑处理。
|
||
|
||
### 10.5 坐标空间
|
||
|
||
不能只读取粒子局部快照直接输出。每帧必须组合:
|
||
|
||
```text
|
||
粒子局部状态
|
||
+ 系统根变换
|
||
+ 当前帧跟随目标产生的有效变换
|
||
= 最终可导出状态
|
||
```
|
||
|
||
同时统一处理 Pixi Y 向下与 Spine Y 向上的坐标转换、旋转方向和父子局部变换。
|
||
|
||
---
|
||
|
||
## 十一、动画归属与时长
|
||
|
||
### 11.1 多动画
|
||
|
||
一个 JSON 包含项目中的多个“所属动画”:
|
||
|
||
```json
|
||
"animations": {
|
||
"animation": {},
|
||
"animation2": {},
|
||
"start": {},
|
||
"loop": {},
|
||
"end": {}
|
||
}
|
||
```
|
||
|
||
- 每个粒子系统只写入它所属的动画;
|
||
- 多个粒子系统可以属于同一动画;
|
||
- 同一动画时长取参与导出的粒子系统中最长者;
|
||
- 较短系统到达末帧后保持符合自身模式的末帧状态;
|
||
- Spine、碰撞体和路径自身时长不参与导出动画时长计算。
|
||
|
||
### 11.2 空动画
|
||
|
||
空动画是否保留遵循“排除无内容动画”设置:
|
||
|
||
- 设置关闭:所属动画列表中的空动画仍输出为 `{}`;
|
||
- 设置开启:没有任何可见粒子动画内容的动画不写入 JSON。
|
||
|
||
### 11.3 循环持续三段动画
|
||
|
||
- 启动段、纯循环段和结束段按用户当前保存的状态导出;
|
||
- 循环衔接帧的粒子身份和视觉状态必须稳定;
|
||
- 纯循环段保留假死粒子的骨骼身份,并通过附件隐藏或透明度 0 表现死亡;
|
||
- 循环首尾接缝不得因关键帧精简产生卡顿或突变;
|
||
- 延迟时间保持现有循环持续语义;
|
||
- 所属动画命名继续沿用编辑器已有逻辑,不由导出器自动改名。
|
||
|
||
### 11.4 时间端点
|
||
|
||
- 时间为 `frameIndex / exportFps`;
|
||
- 时间轴包含可选择的最后端点帧;
|
||
- 循环动画允许保留首尾相同的末端点;
|
||
- 时长不足完整导出帧时按规则向上取整,不能截断最长寿命粒子或拖尾。
|
||
|
||
---
|
||
|
||
## 十二、关键帧烘焙与压缩
|
||
|
||
### 12.1 总体策略
|
||
|
||
采用:
|
||
|
||
```text
|
||
完整逐帧烘焙 → 分类 → 安全精简 → 误差验证
|
||
```
|
||
|
||
不能先减少采样再模拟,也不能简单每隔固定帧保留一帧。
|
||
|
||
### 12.2 离散数据
|
||
|
||
以下数据不能进行数值插值,只保留变化点并使用阶跃语义:
|
||
|
||
- 粒子出生和死亡;
|
||
- 图片显示和隐藏;
|
||
- 粒子图片资源切换;
|
||
- 序列帧附件切换;
|
||
- 拖尾资源切换;
|
||
- 混合模式变化;
|
||
- 假死状态切换。
|
||
|
||
连续多帧相同附件或相同状态只输出第一次变化关键帧。
|
||
|
||
### 12.3 连续数据
|
||
|
||
以下数据先逐帧烘焙,再进行误差受控精简:
|
||
|
||
- 粒子位置;
|
||
- 粒子旋转;
|
||
- 粒子缩放;
|
||
- 粒子颜色和透明度;
|
||
- 拖尾骨骼位置;
|
||
- 拖尾骨骼旋转;
|
||
- 拖尾宽度缩放。
|
||
|
||
精简器检查删除中间关键帧后,Spine 插值结果是否仍在误差范围内。采用以下视觉容差:
|
||
|
||
| 数据 | 建议容差 |
|
||
|---|---:|
|
||
| 粒子位置 | 0.05–0.1 像素(当前实现取 0.1) |
|
||
| 拖尾骨骼位置 | 0.05–0.1 像素(当前实现取 0.1) |
|
||
| 旋转 | 0.01° |
|
||
| 缩放 | 0.01 |
|
||
| 透明度 | 0.01 |
|
||
| RGB | 单通道 1/255 |
|
||
|
||
出生、死亡、附件切换、碰撞突变和循环接缝仍强制保留,不允许跨边界压缩。
|
||
|
||
### 12.4 强制保留点
|
||
|
||
以下位置不得跨越压缩:
|
||
|
||
- 粒子出生帧;
|
||
- 粒子死亡帧;
|
||
- 附件显示、隐藏和切换帧;
|
||
- 碰撞、反弹、暂停和销毁前后;
|
||
- 运动方向突然变化处;
|
||
- 拖尾出现和消失处;
|
||
- 循环首尾衔接区域;
|
||
- 延迟段和正式运动段边界;
|
||
- 旋转角度展开产生的边界。
|
||
|
||
### 12.5 旋转处理
|
||
|
||
压缩前先进行角度展开。例如:
|
||
|
||
```text
|
||
358° → 1° → 4°
|
||
```
|
||
|
||
应转换为:
|
||
|
||
```text
|
||
358° → 361° → 364°
|
||
```
|
||
|
||
避免 Spine 插值时反向旋转一整圈。
|
||
|
||
### 12.6 插值曲线设置
|
||
|
||
- `线性 (Linear)`:连续数据使用线性插值和线性误差精简;
|
||
- `平滑贝塞尔 (Smooth Bézier)`:对连续段拟合贝塞尔,并逐帧检查误差;
|
||
- 贝塞尔拟合不满足容差时必须增加关键帧,不能牺牲精度;
|
||
- 离散数据、突变点、碰撞边界和循环接缝不受平滑贝塞尔设置影响。
|
||
|
||
---
|
||
|
||
## 十三、导出设置标准
|
||
|
||
导出设置是全局编辑器设置,不属于单个粒子系统。必须参与:
|
||
|
||
- 保存配置;
|
||
- 加载配置;
|
||
- 预设加载;
|
||
- 撤回;
|
||
- 旧配置默认值补齐。
|
||
|
||
### 13.1 设置项与默认值
|
||
|
||
| 设置 | 默认值 | 规则 |
|
||
|---|---|---|
|
||
| 图片路径 | `./images/` | 写入 `skeleton.images` |
|
||
| Spine 版本 | `Spine 4.2` | 第一版唯一选项 |
|
||
| 关键帧插值曲线 | `线性 (Linear)` | 可切换平滑贝塞尔 |
|
||
| 导出 FPS | `30` | 支持 1~240 的正整数 |
|
||
| 不写 fps | 关闭 | 只省略 `skeleton.fps` 元数据 |
|
||
| 整数帧对齐 | 开启 | 关键帧位于导出 FPS 的整数帧网格 |
|
||
| 骨骼对象池 | 开启 | 复用粒子骨骼和拖尾链 |
|
||
| 排除无内容动画 | 关闭 | 关闭时保留空动画 `{}` |
|
||
| 默认文件名 | `SpineParticle.json` | 浏览器处理重复下载名称 |
|
||
|
||
### 13.2 导出 FPS 语义
|
||
|
||
修改导出 FPS 时保持动画实际秒数不变。
|
||
|
||
例如:
|
||
|
||
```text
|
||
30f / 30 FPS = 1 秒
|
||
60f / 60 FPS = 1 秒
|
||
```
|
||
|
||
不能在导出 60 FPS 时仍只输出 30 帧并把动画缩短为 0.5 秒。
|
||
|
||
“不写 fps”仅省略 Spine JSON 中的 FPS 元数据,内部烘焙、采样和时间换算仍使用导出 FPS。
|
||
|
||
### 13.3 整数帧对齐
|
||
|
||
开启时:
|
||
|
||
```text
|
||
time = integerFrame / exportFps
|
||
```
|
||
|
||
不能产生小数帧位置。无法整除的尾端时长向上取整,同时保持需要完成的粒子生命周期和拖尾状态。
|
||
|
||
---
|
||
|
||
## 十四、命名与文件规则
|
||
|
||
### 14.1 默认文件名
|
||
|
||
```text
|
||
SpineParticle.json
|
||
```
|
||
|
||
### 14.2 名称安全
|
||
|
||
导出器必须:
|
||
|
||
- 为系统、粒子、拖尾、Slot 和 Attachment 生成稳定名称;
|
||
- 处理空名称、重复名称和非法路径分隔符;
|
||
- 保留用户所属动画名称;
|
||
- 不在没有必要时修改用户可见的图片文件名;
|
||
- 保证同一配置、同一种子和同一导出设置产生稳定命名。
|
||
|
||
---
|
||
|
||
## 十五、代码结构标准
|
||
|
||
导出功能必须使用独立文件,不能把大量逻辑继续堆入 `ParticlePanel.vue`、`Stage.vue` 或 Store。
|
||
|
||
推荐结构:
|
||
|
||
```text
|
||
src/export/
|
||
├─ spineExportSettings.ts
|
||
├─ spineJsonTypes.ts
|
||
├─ particleExportBaker.ts
|
||
├─ spineMeshBuilder.ts
|
||
├─ spineKeyframeReducer.ts
|
||
├─ spineJsonExporter.ts
|
||
└─ spineJsonValidator.ts
|
||
```
|
||
|
||
职责:
|
||
|
||
- `spineExportSettings.ts`:导出设置类型、默认值和旧配置补齐;
|
||
- `spineJsonTypes.ts`:Spine 4.2 JSON 类型;
|
||
- `particleExportBaker.ts`:确定性逐帧模拟和外部关联解除;
|
||
- `spineMeshBuilder.ts`:拖尾骨骼链、权重、UV 和三角形生成;
|
||
- `spineKeyframeReducer.ts`:离散合并和连续时间轴误差精简;
|
||
- `spineJsonExporter.ts`:组装 Skeleton、Bones、Slots、Skins 和 Animations;
|
||
- `spineJsonValidator.ts`:导出前后结构验证和警告。
|
||
|
||
界面中的“导出Spine Json”按钮只负责调用导出入口、显示结果和下载文件。
|
||
|
||
---
|
||
|
||
## 十六、验证与验收标准
|
||
|
||
### 16.1 结构验证
|
||
|
||
导出前检查:
|
||
|
||
- 骨骼名称唯一;
|
||
- 父骨骼先于子骨骼;
|
||
- Slot 引用的骨骼存在;
|
||
- Skin 引用的 Slot 存在;
|
||
- Attachment Timeline 引用的附件存在;
|
||
- Mesh 骨骼索引有效;
|
||
- Mesh 权重和正确;
|
||
- UV、顶点和三角形索引数量匹配;
|
||
- 动画时间递增;
|
||
- 颜色为有效 RGBA;
|
||
- 所有数字有限,不出现 `NaN` 或 `Infinity`。
|
||
|
||
### 16.2 Runtime 验证
|
||
|
||
生成 JSON 后,使用项目内 Spine 4.2 Runtime 进行一次解析验证。解析失败时不应下载伪成功文件,应显示明确错误位置。
|
||
|
||
图片缺失不属于 JSON 结构失败,只显示警告。
|
||
|
||
### 16.3 视觉验证
|
||
|
||
至少对以下帧进行编辑器画布与导出结果对照:
|
||
|
||
- 第一帧;
|
||
- 粒子第一次出生帧;
|
||
- 最大粒子数量附近;
|
||
- 图片或序列帧切换帧;
|
||
- 碰撞发生前后;
|
||
- 路径或 Spine 跟随运动中间帧;
|
||
- 拖尾明显弯曲帧;
|
||
- 最后一帧;
|
||
- 纯循环首帧和末帧。
|
||
|
||
对照内容包括:
|
||
|
||
- 粒子数量;
|
||
- 粒子位置;
|
||
- 旋转与缩放;
|
||
- 图片资源;
|
||
- 颜色与透明度;
|
||
- 绘制顺序;
|
||
- 拖尾位置、方向、宽度和弯曲;
|
||
- 循环接缝。
|
||
|
||
### 16.4 文件体积验收
|
||
|
||
- 优先通过对象池、重复状态合并和误差受控关键帧精简减小文件;
|
||
- 拖尾必须使用加权 Mesh,不能用逐帧 Deform 换取实现简单;
|
||
- 不能为了缩小文件破坏碰撞、噪声、序列帧或循环精度;
|
||
- 对象池关闭时允许文件显著增大,但应给出预计规模提示。
|
||
|
||
---
|
||
|
||
## 十七、当前实施状态
|
||
|
||
截至本文落盘:
|
||
|
||
1. 导出范围、格式目标和关键规则已对齐;
|
||
2. 导出设置面板已实现;
|
||
3. 导出设置已接入保存、加载、预设、撤回和旧配置补齐;
|
||
4. 默认文件名已定义为 `SpineParticle.json`;
|
||
5. “导出Spine Json”按钮尚未接入 JSON 生成;
|
||
6. 正式导出代码必须等待用户明确的“开始”指令后实施;
|
||
7. 开始实现前应下载并核对 Spine 官方 GitHub 仓库中的 Spine 4.2 加权 Mesh 和多动画 JSON 示例。
|
||
|
||
---
|
||
|
||
## 十八、禁止偏离项摘要
|
||
|
||
以下规则未经重新确认不得改变:
|
||
|
||
1. 只导出可见粒子系统;
|
||
2. 不导出碰撞体、路径和原 Spine 对象;
|
||
3. 外部关联必须烘焙为独立动画;
|
||
4. 第一版只支持 Spine 4.2;
|
||
5. 图片文件不导出,只写正确路径;
|
||
6. 缺图不阻止导出;
|
||
7. 序列帧只使用一根粒子骨骼;
|
||
8. 拖尾必须使用加权 Mesh 和拖尾骨骼链;
|
||
9. 拖尾不得正式导出为逐帧 Deform;
|
||
10. 先逐帧烘焙,再安全精简关键帧;
|
||
11. Setup Pose 普通骨骼位移和旋转为 0、缩放为 1;
|
||
12. 拖尾子骨骼保留正确绑定链位置;
|
||
13. Setup Pose 图片和 Mesh 默认透明度为 0;
|
||
14. 修改 FPS 时保持实际秒数不变;
|
||
15. 空动画是否保留遵循“排除无内容动画”;
|
||
16. 默认文件名为 `SpineParticle.json`;
|
||
17. 导出功能必须拆分为独立代码模块;
|
||
18. 导出主要用途是重新导入 Spine 编辑器继续编辑。
|