You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot引擎出现body set shape disabled等错误导致游戏崩溃如何解决

问题原因
  • 核心逻辑漏洞:你在_on_DangerArea_body_entered信号回调中直接写了while(trigger)循环,且没有做协程重复启动的拦截。Area2D的body_entered信号可能因为飞船在区域内移动时的碰撞边缘判定、物理帧同步偏差被触发多次,每触发一次就会启动一个独立的协程循环生成导弹,数百个并行协程同时运行就会导致每秒生成200-300个导弹节点。
  • 崩溃的直接诱因:短时间内生成大量带碰撞盒的RigidBody2D节点,Godot物理线程无法承载过量的碰撞计算任务,就会抛出body set shape disabled、body set shape as one-way collision的底层错误,最终导致游戏崩溃。
修复方案

修改platform节点的挂载脚本,新增协程运行状态标记,避免重复启动生成逻辑,同时调整导弹的挂载节点,防止父节点物理属性干扰导弹运行,修改后代码如下:

extends StaticBody2D

var trigger = false
var is_spawning = false # 标记生成协程是否已在运行,避免重复启动
var missileScene = preload("res://scenes/Missile.tscn")

func _on_DangerArea_body_entered(body):
    if body is KinematicBody2D:
        trigger = true
        # 仅当没有运行中的生成协程时才启动新逻辑
        if not is_spawning:
            is_spawning = true
            while(trigger):
                var missile = missileScene.instance()
                # 导弹直接挂载到场景根节点,不要作为platform子节点,避免继承StaticBody2D的物理属性
                get_tree().root.add_child(missile)
                # 同步导弹出生位置为发射点的全局坐标
                missile.global_position = $SpawnPosition.global_position
                yield(get_tree().create_timer(3), "timeout")
            # 退出循环后重置状态标记
            is_spawning = false

func _on_DangerArea_body_exited(body):
    if body is KinematicBody2D:
        trigger = false

额外优化建议

  • 给missile节点添加屏幕外检测逻辑,飞出可视区域后调用queue_free()销毁,避免冗余节点长期占用性能。
  • 检查Area2D的碰撞层、碰撞掩码配置,确保仅和飞船所在的物理层交互,减少不必要的信号触发。

内容的提问来源于stack exchange,提问作者Peppe32

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 07:09:03