BulletSystem.md 4.7 KB

子弹系统说明

适用版本:重构后的 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 结构

{
  "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 等会触发销毁。
  • 是否配置了极短 maxLifetimemaxRangepenetration = 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() 输出实时状态进行排查。