Files
SpineParticlesWeb/Document/阶段十二开发日志.md
T
2026-10-22 17:23:38 +08:00

468 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 网页粒子系统 · 阶段十二开发日志
> 阶段定位:**子发射器、Spine 预览层级、贴图轴点、独立 AB 循环与多版本导出完善**
> 完成日期:2026-10-22
> 工程目录:`/Users/tianmokeji/Desktop/SpineParticle`
> 技术栈:Vue 3 + TypeScript + Pinia + PixiJS 7 + Spine Runtime + Vite
---
## 一、阶段结论
阶段十二在阶段十一的粒子编辑与 Spine 导出体系上,补齐了复杂效果编排和实际项目使用中需要的能力。
本阶段重点不再是单一粒子的基础参数,而是粒子系统之间的关系、粒子与 Spine 场景的关系,以及烘焙导出后的可编辑性。完成后的编辑器可以制作父粒子触发的多层子粒子效果,在 Spine 插槽上下预览粒子,对贴图轴点进行可视化调整,并使用独立的 A/B 区间检查循环衔接。
阶段十二主要完成:
1. 新增出生、死亡、碰撞三类子发射器事件;
2. 新增子发射器目标、发射概率、属性继承和碰撞触发上限;
3. 建立父子发射器关系、循环依赖保护和事件链深度限制;
4. 子发射器进入场景树嵌套显示,不再独立自动发射;
5. 时间轴增加子发射器活动区间、启动标记和完整时长计算;
6. AB 循环改为独立开关和上浮输入窗,不再依赖持续发射循环;
7. 新增粒子在 Spine 插槽图片之上、之下的预览层级;
8. 渲染层级支持运行时 drawOrder 变化,并保持世界坐标稳定;
9. 图片资源卡新增可视化贴图轴点编辑器;
10. 贴图轴点支持画布拖动、滚轮缩放、坐标输入和超出图片范围;
11. 贴图轴点写入 Spine 附件偏移,参与最终烘焙导出;
12. Spine JSON 导出扩展为 3.8、4.0、4.1、4.2、4.3;
13. 修复子发射器在导出前暂停补齐时没有进入逐帧事件录制的问题;
14. 修复子发射器因自身生命周期较短而被错误截断帧的问题;
15. 增加子发射器、碰撞次数、AB 循环和层级绑定的配置迁移。
阶段十二完成后,粒子编辑器已经具备从设计、组合、预览、循环检查到 Spine 烘焙导出的完整工作流。
---
## 二、子发射器系统
### 2.1 事件类型
每条规则可选择一种父粒子事件:
| 事件 | 触发时机 |
|---|---|
| 出生 | 父粒子刚生成时触发 |
| 死亡 | 父粒子生命周期结束时触发 |
| 碰撞 | 父粒子接触启用的碰撞对象时触发 |
事件规则包含:
- 目标粒子系统;
- 发射概率;
- 碰撞次数限制;
- 属性继承;
- 颜色继承方式。
### 2.2 目标系统
被任意有效事件规则引用的粒子系统会成为子发射器:
- 不再独立自动发射;
- 只由父粒子事件生成;
- 在场景对象列表中嵌套到父系统下方;
- 在时间轴中使用灰色子发射器轨道;
- 移除引用或关闭“开启子发射器”后恢复普通系统。
子发射器选择列表会排除自身和全部上游父系统,避免形成循环引用。
事件链最多继续两级,防止跨系统事件无限递归。
### 2.3 发射数量与延迟
子发射器仍使用自身的发射模式:
- 爆发模式:每次事件生成“单次数量”颗粒子;
- 持续模式:每次事件生成一颗事件粒子;
- 子发射器 `delay`:父事件之后再等待指定秒数;
- 延迟后的粒子仍会正常参与碰撞、修改器和生命周期更新。
### 2.4 碰撞次数限制
碰撞事件可设置“碰撞次数限制”:
- 默认值:1;
- 整数范围:1~4;
- 按每颗父粒子独立累计;
- 粒子出生时碰撞次数归零;
- 输入超出范围时立即钳制;
- 只在事件类型为“碰撞”时显示。
该参数用于抑制粒子反弹、悬停或反复进出碰撞体导致的同一颗父粒子重复生成子粒子。
### 2.5 属性继承
子发射器支持多选继承:
| 属性 | 当前语义 |
|---|---|
| 颜色 | 按通道相加,或使用父粒子颜色覆盖 |
| 大小 | 子粒子自身缩放 × 父粒子当前渲染缩放 |
| 旋转 | 作为子发射系统整体发射方向和初始朝向偏移 |
| 生命周期 | 覆盖子粒子生命周期,使用父粒子的完整 `maxLife` |
生命周期继承使用父粒子的完整生命周期,不使用剩余寿命,也不与子粒子自身寿命相加。
### 2.6 烘焙要求
子发射器不能脱离父事件单独预热。阶段十二修复了两处烘焙问题:
1. 暂停时为根系统补帧后,旧逻辑会过早将整段动画标记为已烘焙,导致导出跳过事件录制;
2. 导出器按系统自身生命周期截断帧,导致较晚出现的子发射器帧被裁掉。
现在只有所有系统都具备完整帧缓存才可标记烘焙完成;子发射器导出时保留完整录制时间轴。
---
## 三、时间轴与 AB 循环
### 3.1 子发射器时间轴
子发射器在时间轴上显示为灰色条:
- 起点为首次父事件时间加子发射器延迟;
- 末端包含最后一次触发后的粒子生命周期;
- 子发射器圆点标记系统启动时刻,不随子发射器 delay 拖动;
- 拖动灰色条会增加延迟,但不能移动到父事件发生之前;
- 总帧数会递归包含子发射器链;
- 子发射器延长总长后,预览视口会自动扩展;
- 关闭子发射器后,目标系统的独立时长重新计入总帧数。
### 3.2 持续循环
时间轴的持续循环按钮只控制播放是否回到起点,与 AB 区间开关相互独立。
### 3.3 AB 循环
AB 循环现在是一个独立开关:
- 关闭时不显示 A/B 输入框,播放完整时间轴;
- 开启时在时间轴上方浮出输入窗;
- A、B 由用户直接输入;
- 关闭后保留原值,下次开启可以继续使用;
- “持续循环”开启时,AB 区间重复播放;
- “持续循环”关闭时,播放到 B 后停止;
- AB 状态和数值会进入配置文件。
### 3.4 循环衔接原则
循环段仍遵守既有约束:
- A/B 必须是精确的衔接状态;
- 不通过复制首帧数值到尾帧制造表面闭环;
- 粒子位置跳变只允许发生在粒子不可见时;
- 循环开始、循环衔接和结束段需要在衔接帧强制 K 帧;
- 强制 K 帧用于保留当前状态,方便后续在 Spine 中拆分动画;
- 导出数据保留闭合边界,预览可以跳过数学边界帧避免停顿。
---
## 四、Spine 插槽渲染层级
### 4.1 预览层级
粒子系统可选择:
- 最上层;
- Spine 插槽;
- 指定插槽图片之上;
- 指定插槽图片之下。
插槽列表按 drawOrder 排列,并显示附件信息和搜索框。
### 4.2 动画 drawOrder
Spine 动画改变插槽绘制顺序时,编辑器会按当前动画帧的 drawOrder 重新解析实际挂载位置。
粒子容器使用坐标补偿抵消插槽骨骼变换,因此改变显示层级不会改变粒子在场景中的世界位置。
同一插槽可以同时承载多个粒子系统。
### 4.3 导出边界
渲染层级只影响编辑器预览,不写入 Spine 导出数据。
若需要粒子位于 Spine 插槽之间,应在 Spine 编辑器中建立对应层级,再放入烘焙后的粒子骨骼和插槽。
---
## 五、贴图轴点编辑器
图片资源卡增加“贴图轴点”开关。
开启后可以:
- 在图片预览中直接拖动轴点;
- 右键拖动画布;
- 使用滚轮缩放画布;
- 输入精确 X/Y 百分比;
- 将轴点设置在图片范围之外;
- 放大到全屏工作;
- 恢复默认居中;
- 重置当前图片轴点。
轴点十字线保持固定屏幕尺寸,并延伸为横竖无限长参考线。
轴点和开关状态跟随每张图片资源独立保存,不会因修改其他粒子参数而重置。
导出时轴点会转换为 Spine Region 附件的偏移,属于实际烘焙数据。
---
## 六、Spine 资源与多版本导出
### 6.1 Spine 场景对象
支持加载 Spine 的 skeleton、atlas 和图片资源,并提供:
- 动画列表与预览;
- 骨骼层级树;
- 骨骼搜索和选择;
- 插槽列表与附件名称;
- 动画 drawOrder;
- 粒子发射器跟随骨骼;
- 粒子预览插槽层级。
支持 Spine 3.8、4.0、4.1、4.2、4.3 资源预览。
### 6.2 JSON 导出
导出设置支持:
- Spine 3.8 / 4.0 / 4.1 / 4.2 / 4.3;
- 图片路径;
- 线性或平滑贝塞尔;
- 导出 FPS;
- 不写 fps;
- 整数帧对齐;
- 骨骼对象池;
- 排除无内容动画。
Spine 3.8 不支持 4.x 的逐通道数组贝塞尔,导出时会转换为经过容差精简的分段线性关键帧。
### 6.3 图片与工程包
导出入口包含:
- Spine JSON;
- images 图片 ZIP;
- 通过本地连接器生成 `.spine` 工程包。
连接器仅监听本机地址,使用已安装的 Spine 进行转换,并自动匹配项目 JSON 版本。
---
## 七、当前完整功能模块
### 7.1 配置管理
- 保存配置;
- 加载配置;
- 预设;
- 快捷键保存;
- 系统设置与工程配置分离;
- 配置版本校验和旧字段迁移。
### 7.2 场景对象
- 粒子系统;
- 碰撞体;
- 贝塞尔路径;
- Spine 资源;
- 对象复制;
- 显隐控制;
- 对象树和父子发射器嵌套。
### 7.3 发射模式
- 持续发射;
- 单次爆发;
- 延迟;
- 常规持续;
- 循环持续;
- 循环开始、纯循环、结束三段。
### 7.4 发射器形状
- 点;
- 圆形环带;
- 矩形环带;
- 锥形;
- 路径出生线;
- 固定、随机、径向、路径法线、路径切线角度。
### 7.5 粒子属性
- 生命周期;
- 速度;
- 缩放;
- 初始旋转;
- 生命周期内速度、缩放、旋转变化;
- 固定、随机、曲线取值;
- 多轴分离缩放。
### 7.6 外观与资源
- 单图与序列帧;
- 多图片权重随机;
- 图片缩放和贴图轴点;
- 固定色、随机色、生命周期渐变;
- 每张图片独立透明度;
- 正常、相加、相乘、滤色混合;
- 粒子系统透明度曲线。
### 7.7 修改器
- 移动噪声;
- 重力;
- 风力;
- 全局力场;
- 漩涡;
- 吸附;
- 阻尼;
- 碰撞与碰撞响应;
- 拖尾;
- 路径跟随;
- Spine 骨骼跟随;
- 子发射器。
### 7.8 时间轴
- 播放、暂停和逐帧;
- 持续循环;
- 独立 AB 循环;
- 自动总时长;
- 发射段和粒子存在段;
- Spine 动画条;
- 子发射器灰色条;
- 多动画归属;
- 循环段快捷范围已由独立 AB 输入替代。
### 7.9 导出
- Spine JSON;
- images ZIP;
- `.spine` 工程包;
- 子发射器事件结果烘焙;
- 碰撞结果烘焙;
- 路径和 Spine 跟随结果烘焙;
- 拖尾加权 Mesh;
- 关键帧精简;
- 结构校验。
---
## 八、数据结构与兼容
阶段十二新增或完善的主要配置字段:
```text
ParticleEventRule.collisionLimit
TimelineState.abLoop
EditorConfigFile.timeline.playbackEndAuto
EditorConfigFile.timeline.abLoop
EmitterConfig.renderLayerMode
EmitterConfig.renderLayerSpineId
EmitterConfig.renderLayerSlotName
EmitterConfig.renderLayerSlotPosition
EmitterConfig.renderLayerFollowAttachment
ParticleImageResource.anchorX
ParticleImageResource.anchorY
```
旧配置处理:
- 缺少碰撞限制时补为 1;
- 缺少 AB 开关时默认关闭;
- 旧 B 帧若原本是完整末帧,加载时迁移到新的完整末帧;
- 无渲染层级字段时恢复“最上层”;
- 无轴点字段时恢复 0.5 / 0.5;
- 关闭“开启子发射器”后,保留规则但不再把目标识别为子发射器。
---
## 九、主要代码落点
| 文件 | 阶段十二职责 |
|---|---|
| `src/core/particleEmitter.ts` | 事件触发、碰撞计数、子粒子生成、属性继承 |
| `src/core/subEmitterIds.ts` | 子发射器引用、上游关系和循环依赖保护 |
| `src/core/subEmitterTiming.ts` | 子发射器触发区间和总时长 |
| `src/views/stage/emitterSync.ts` | 跨系统事件分发、概率、碰撞上限、自动发射切换 |
| `src/views/stage/renderLayer.ts` | 插槽渲染目标解析 |
| `src/views/Stage.vue` | 事件逐帧录制、帧缓存、子发射器烘焙 |
| `src/views/Timeline.vue` | 子发射器条、AB 循环浮窗、启动标记、视图缩放 |
| `src/views/ImageResourceCard.vue` | 图片轴点开关和资源卡入口 |
| `src/views/PivotEditor.vue` | 轴点画布、缩放、拖动和全屏编辑 |
| `src/views/particle-panel/ParticleModifiersSection.vue` | 子发射器卡片、继承和碰撞限制 UI |
| `src/views/particle-panel/ParticleAppearanceSection.vue` | 渲染层级和资源面板 |
| `src/export/spineJsonExporter.ts` | 多版本 JSON、子发射器完整帧导出、轴点偏移 |
| `src/editor/editorConfig.ts` | 配置保存、加载和旧配置迁移 |
| `src/store/particleStore.ts` | 时间轴、独立 AB、总帧数和播放范围 |
---
## 十、验证结果
阶段十二执行并通过:
```text
npm run test:particle-events
npm run test:sub-emitter-timeline
npm run test:timeline
npm run test:loop-seam
npm run test:render-layer
npm run test:spine-json
npm run test:vortex
npx vue-tsc -b
npm run build
```
浏览器实测包括:
- 出生、死亡、碰撞事件均能生成目标子粒子;
- 碰撞次数限制能减少重复触发;
- 关闭子发射器后,对象树、自动发射和时间轴恢复正常;
- Spine 插槽层级支持动画 drawOrder;
- 轴点画布支持拖动、滚轮缩放和超出边界坐标;
- AB 关闭播放完整时间轴,开启后按用户输入区间播放;
- 子发射器在导出前能生成完整帧缓存;
- 导出 JSON 包含一级和二级子发射器轨道;
- 当前测试场景导出骨骼数由错误的 8 根恢复为 140 根;
- `Burst_Collid_0`~`Burst_Collid_89` 已进入 Spine JSON;
- `dist/` 生产构建成功。
---
## 十一、当前边界
- 子发射器事件链最多两级;
- 碰撞次数限制为 1~4;
- 渲染层级仅影响编辑器预览,不参与 Spine 动画数据导出;
- 贴图轴点会烘焙进 Spine 附件偏移;
- `.spine` 工程包需要本机安装并启动连接器;
- Spine 3.8 的贝塞尔表达受旧格式限制,会转换为精简线性关键帧;
- 非常长的子发射器延迟会增加录制与导出时长;
- 预览循环和导出闭环继续遵守“精确衔接、不可见时才允许跳变”的约束。
---
## 十二、阶段十二最终状态
阶段十二完成后,SpineParticle 已具备:
- 多粒子系统父子事件编排;
- 出生、死亡、碰撞三种事件链;
- 子粒子颜色、大小、旋转和生命周期继承;
- 可控的重复碰撞触发;
- Spine 插槽上下预览层级;
- 可视化贴图轴点;
- 独立 AB 循环检查;
- 子发射器完整烘焙;
- Spine 3.8~4.3 JSON 导出;
- JSON、图片包和 `.spine` 工程包输出;
- 配置文件、预设、复制和撤回完整联动。
至此,阶段十二“复杂粒子编排与 Spine 生产链路完善”完成落盘。