# 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 编辑器继续编辑。