# 子弹系统说明 > 适用版本:重构后的 WeaponBullet / BulletEffects 架构(2025-07-01) --- ## 总览 ``` +-------------------+ | weapons.json | +-------------------+ | | 解析后生成 WeaponConfig v +-------------------+ | WeaponBullet | << 场景节点挂载脚本 (入口) +-------------------+ | | | | | | | +--------------------+ ④ 生命周期 | | +-----------------------+ ③ 命中效果 | +--------------------------+ ② 弹道 +-----------------------------+ ① 数量/生成 ``` * **WeaponBullet.ts**:统一控制器。读取 `weapons.json`,实例化子弹并把四大维度配置分发给各模块。 * **BulletEffects 目录**:四大功能模块均位于此处。 1. **BulletCount.ts** ‑ 计算一次开火实际生成多少颗子弹、位置、延迟等。 2. **BulletTrajectory.ts** ‑ 控制运动;支持直线、抛物、弧线、追踪、弹射方向改变等。 3. **BulletHitEffect.ts** ‑ 命中效果可叠加;负责播放命中特效、爆炸、灼烧区、计算伤害、改变弹道方向等。 4. **BulletLifecycle.ts** ‑ *唯一* 负责子弹的生死决策;管理寿命、射程、穿透/弹射计数、回旋镖返回、越界、自毁等。 ## weapons.json 结构 ```jsonc { "weapons": [ { "id": "pea_shooter", "stats": { "damage": 20, "bulletSpeed": 30, ... }, "bulletConfig": { "count": { /* ① BulletCount 配置 */ }, "trajectory": { /* ② BulletTrajectory 配置 */ }, "hitEffects": [ /* ③ BulletHitEffect 列表 */ ], "lifecycle": { /* ④ BulletLifecycle 配置 */ }, "visual": { /* 资源路径:子弹预制、特效等 */ } } } ] } ``` 所有视觉资源路径现已统一为 `Animation/WeaponTx/txXXXX/txXXXX`,可直接被 `resources.load` 成功解析。 ## BulletLifecycle 工作流程 1. **WeaponBullet.init** 时调用 `bulletLifecycle.init(cfg, startPos)`。 2. **BulletLifecycle.update(dt)** 每帧执行: * 累积生存时间、飞行距离。 * 检查 `maxLifetime / maxRange / 越界` 等条件。 * 判断 `state.shouldDestroy` 后调用 `this.node.destroy()` —— *场景中唯一允许直接销毁子弹的位置*。 3. **命中时**,`WeaponBullet.onHit` 只负责: * 将碰撞信息转发给 `bulletHitEffect.processHit()`(产生伤害, 可能更改弹道)。 * 调用 `bulletLifecycle.onHit(otherNode)` 更新内部计数/阶段。 * 绝不直接 `destroy()` 结点。 因此 **子弹是否消失** 完全取决于 BulletLifecycle 的配置与状态。 ## 为什么可能会"莫名其妙"消失? 旧版代码中,`WeaponBullet.onHit` 和其他脚本曾直接 `this.node.destroy()`,与 `BulletLifecycle` 产生并行决策。 已做的调整: 1. `WeaponBullet.onHit` 不再调用 `this.node.destroy()`。 2. `WeaponBullet.forceDestroy` 仅调用 `bulletLifecycle.forceDestroy()`。 3. 其他脚本未再出现针对子弹的直接销毁;如有特殊 Debug/容错场景(创建失败等)例外处理不影响运行时逻辑。 若仍有异常消失,请检查: * 对应武器的 `lifecycle.type` 是否设置为 `hit_destroy` / `range_limit` 等会触发销毁。 * 是否配置了极短 `maxLifetime`、`maxRange` 或 `penetration = 0` 等。 * 是否飞出 Canvas +200px 容差导致 `checkOutOfBounds()` 自毁。 ## 扩展 / 自定义 * 新增命中效果:在 `BulletHitEffect.processEffect()` 中实现,并在 `weapons.json -> hitEffects` 列表添加即可。 * 新增生命周期模式:在 `BulletLifecycleConfig.type` 联合类型加入枚举 + 对应处理函数。 * 新增弹道:在 `BulletTrajectory` 中扩展 `_update*()` 逻辑并在 `trajectory.type` 中配置。 --- ### 关键脚本一览 | 模块 | 文件 | 说明 | | ---- | ---- | ---- | | 数量 & 生成 | `BulletEffects/BulletCount.ts` | 计算子弹生成阵列、偏移、延迟 | | 弹道 | `BulletEffects/BulletTrajectory.ts` | 速度、重力、追踪、弧线、方向变化 | | 命中 | `BulletEffects/BulletHitEffect.ts` | 叠加型命中效果栈、特效播放 | | 生命周期 | `BulletEffects/BulletLifecycle.ts` | 子弹存亡唯一裁决者 | | 入口 | `WeaponBullet.ts` | 读取配置 → 初始化上述 4 组件 | --- > **结论**:现在所有子弹的生成、运动、特效与销毁都遵循统一配置与单一生命周期管理。请将旧逻辑移除后再行测试,如仍有问题,可通过 `weaponBullet.getBulletStatus()` 输出实时状态进行排查。