181404010226 5 mesiacov pred
rodič
commit
1fca7aa16b

+ 7 - 12
assets/scripts/CombatSystem/WeaponBullet.ts

@@ -350,19 +350,16 @@ export class WeaponBullet extends Component {
         // 处理命中效果
         const hitResult: HitResult = this.bulletHitEffect.processHit(otherNode, contactWorldPos);
         
-        // 处理生命周期
-        const shouldDestroy: boolean = this.bulletLifecycle.onHit(otherNode);
-        
-        // 合并决策逻辑
-        if (shouldDestroy || hitResult.shouldDestroy) {
-            console.log('💀 子弹被销毁');
-            this.node.destroy();
-        } else if (hitResult.shouldRicochet) {
+        // 通知生命周期组件发生命中(可能影响内部计数或阶段)
+        if (this.bulletLifecycle) {
+            this.bulletLifecycle.onHit(otherNode);
+        }
+        // 不直接销毁,交由 BulletLifecycle 自行处理
+        // 生命周期和命中效果自行决定是否销毁;此处不再直接销毁,由 BulletLifecycle.update() 完成
+        if (hitResult.shouldRicochet) {
             console.log('🎾 子弹发生弹射');
-            // 弹射逻辑已在命中效果中处理
         } else if (hitResult.shouldContinue) {
             console.log('🏹 子弹继续飞行');
-            // 继续飞行,不做额外处理
         }
     }
     
@@ -398,8 +395,6 @@ export class WeaponBullet extends Component {
     public forceDestroy() {
         if (this.bulletLifecycle) {
             this.bulletLifecycle.forceDestroy();
-        } else {
-            this.node.destroy();
         }
     }
     

+ 103 - 0
docs/BulletSystem.md

@@ -0,0 +1,103 @@
+# 子弹系统说明
+
+> 适用版本:重构后的 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()` 输出实时状态进行排查。