Browse Source

子弹销毁逻辑整理

181404010226 5 months ago
parent
commit
8c3d0d8590

+ 44 - 60
assets/scripts/CombatSystem/BallController.ts

@@ -455,31 +455,22 @@ export class BallController extends Component {
             tag: collider ? collider.tag : 'unknown'
         });
 
-        // 移除可能存在的事件监听
-        this.activeBall.off(Contact2DType.BEGIN_CONTACT);
-        this.activeBall.off(Contact2DType.END_CONTACT);
-        this.activeBall.off(Contact2DType.PRE_SOLVE);
-        this.activeBall.off(Contact2DType.POST_SOLVE);
-        
-        // 注册单个碰撞体的回调函数
-        this.activeBall.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
-        this.activeBall.on(Contact2DType.END_CONTACT, this.onEndContact, this);
-        this.activeBall.on(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
-        this.activeBall.on(Contact2DType.POST_SOLVE, this.onPostSolve, this);
-        
-        // 注册全局碰撞回调函数
+        // === 使用全局回调监听器 ===
         if (PhysicsSystem2D.instance) {
-            // 移除可能存在的全局监听器
+            // 先移除旧监听,避免重复注册
             PhysicsSystem2D.instance.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
             PhysicsSystem2D.instance.off(Contact2DType.END_CONTACT, this.onEndContact, this);
-            
-            // 注册全局监听器
+            PhysicsSystem2D.instance.off(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
+            PhysicsSystem2D.instance.off(Contact2DType.POST_SOLVE, this.onPostSolve, this);
+
             PhysicsSystem2D.instance.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
             PhysicsSystem2D.instance.on(Contact2DType.END_CONTACT, this.onEndContact, this);
+            PhysicsSystem2D.instance.on(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
+            PhysicsSystem2D.instance.on(Contact2DType.POST_SOLVE, this.onPostSolve, this);
             console.log('✅ 已注册全局碰撞监听器');
         }
-        
-        console.log('✅ 已注册所有碰撞事件监听器');
+
+        console.log('✅ 小球碰撞组件设置完成');
         console.log('⚙️ === 碰撞组件设置完成 ===');
     }
 
@@ -701,20 +692,6 @@ export class BallController extends Component {
         }
         console.log('✅ 子弹实例创建成功:', bullet.name);
         
-        // 在添加到场景之前,先禁用可能引起问题的物理组件
-        const rigidBody = bullet.getComponent(RigidBody2D);
-        const collider = bullet.getComponent(Collider2D);
-        
-        if (rigidBody) {
-            rigidBody.enabled = false;
-            console.log('🔧 临时禁用刚体组件');
-        }
-        
-        if (collider) {
-            collider.enabled = false;
-            console.log('🔧 临时禁用碰撞组件');
-        }
-        
         // 获取子弹控制器并设置发射位置
         const bulletController = bullet.getComponent(BulletController);
         if (!bulletController) {
@@ -722,43 +699,50 @@ export class BallController extends Component {
             bullet.destroy();
             return;
         }
-        console.log('✅ 获取到子弹控制器组件');
-        
-        // 设置发射位置
-        bulletController.setFirePosition(firePosition);
-        
-        // 将子弹添加到GameArea中
+
+        // 查找GameArea
         const gameArea = find('Canvas/GameLevelUI/GameArea');
         if (!gameArea) {
             console.error('❌ 找不到GameArea节点');
             bullet.destroy();
             return;
         }
-        
-        console.log('🎯 将子弹添加到GameArea(物理组件已禁用)...');
+
+        // 计算放置位置(先转换为本地坐标,避免出现原点闪烁)
+        const gameAreaTrans = gameArea.getComponent(UITransform);
+        const localPos = gameAreaTrans ? gameAreaTrans.convertToNodeSpaceAR(firePosition) : new Vec3();
+
+        // 在添加到场景之前,先禁用可能引起问题的物理组件
+        const rigidBody = bullet.getComponent(RigidBody2D);
+        const collider = bullet.getComponent(Collider2D);
+
+        if (rigidBody) {
+            rigidBody.enabled = false;
+        }
+        if (collider) {
+            collider.enabled = false;
+        }
+
+        // 设置位置再添加到场景,避免视觉闪烁
+        bullet.position = localPos;
         gameArea.addChild(bullet);
-        console.log('✅ 子弹已添加到GameArea');
-        
-        // 延迟重新启用物理组件,确保场景树已稳定
+
+        // 设定发射位置供 BulletController 使用
+        bulletController.setFirePosition(firePosition);
+
+        // 延迟启用物理组件,确保 Box2D world 已就绪,避免 m_world 报错
         this.scheduleOnce(() => {
-            if (bullet && bullet.isValid) {
-                console.log('🔧 重新启用物理组件...');
-                
-                if (rigidBody && rigidBody.isValid) {
-                    rigidBody.enabled = true;
-                    console.log('✅ 刚体组件已重新启用');
-                }
-                
-                if (collider && collider.isValid) {
-                    collider.enabled = true;
-                    console.log('✅ 碰撞组件已重新启用');
-                }
-                
-                console.log('✅ 物理组件重新启用完成');
+            if (!bullet || !bullet.isValid) return;
+
+            if (rigidBody && rigidBody.isValid) {
+                rigidBody.enabled = true;
             }
-        }, 0.1);
-        
-        console.log('✅ 子弹发射成功,将在0.1秒后激活物理系统');
+            if (collider && collider.isValid) {
+                collider.enabled = true;
+            }
+        }, 0.05);
+
+        console.log('✅ 子弹生成完毕并将在 0.05s 后激活物理组件');
         console.log('🔫 === 子弹创建完成 ===');
     }
     

+ 5 - 4
assets/scripts/CombatSystem/BulletController.ts

@@ -278,15 +278,16 @@ export class BulletController extends Component {
      * 如果子弹飞出 GameArea 边界(留有一定安全距离)则自动销毁
      */
     private checkOutOfBounds() {
-        const gameArea = find('Canvas/GameLevelUI/GameArea');
-        if (!gameArea || !this.node || !this.node.isValid) return;
+        // 使用整个屏幕(Canvas)范围判定,而不是 GameArea
+        const canvas = find('Canvas');
+        if (!canvas || !this.node || !this.node.isValid) return;
 
-        const uiTransform = gameArea.getComponent(UITransform);
+        const uiTransform = canvas.getComponent(UITransform);
         if (!uiTransform) return;
 
         const halfWidth = uiTransform.width / 2;
         const halfHeight = uiTransform.height / 2;
-        const center = gameArea.worldPosition;
+        const center = canvas.worldPosition;
 
         const left = center.x - halfWidth;
         const right = center.x + halfWidth;