Godot 4场景切换异常:首次报错但成功,二次切换失效求助
Godot场景切换错误及修复方案
错误原因分析
你遇到的两个问题根源一致:在Area2D的body_shape_entered物理信号回调中直接调用场景切换函数change_scene_to_file。
Godot的物理信号回调属于物理帧处理阶段,此时引擎正在处理碰撞检测等物理逻辑,不允许执行修改场景树的操作(比如切换场景),否则会触发"This function can't be used during the in/out signal"错误。第一次切换虽然看似成功,但已经破坏了引擎的运行状态,导致后续场景切换完全失效。
具体修复步骤
1. 延迟执行场景切换
将场景切换操作从物理信号回调中剥离,使用call_deferred延迟到物理帧处理完成后执行:
修改GameManager.gd中的碰撞回调函数及新增切换逻辑:
func _on_area_2d_body_shape_entered(_body_rid, body, _body_shape_index, _local_shape_index): if body.name == "CharacterBody2D": Levels.level += 1 # 延迟执行场景切换,避开物理信号处理阶段 call_deferred("_switch_to_target_level", Levels.level) # 新增专门的场景切换函数 func _switch_to_target_level(target_level: int): get_tree().change_scene_to_file("res://scenes/level_" + str(target_level) + ".tscn")
2. 确保Levels单例状态正确
确认Levels是自动加载的单例(在项目设置的"自动加载"列表中添加),否则每次场景切换后Levels.level会被重置,导致关卡计数异常。
3. 验证信号连接
检查每个关卡场景中的Area2D节点,确保body_shape_entered信号已正确连接到GameManager的_on_area_2d_body_shape_entered函数(可以在编辑器的"信号"面板中确认)。
额外注意事项
- 避免在任何物理相关的回调(如
_physics_process、碰撞信号)中执行场景切换、节点销毁/添加等场景树修改操作,这类操作都应该用call_deferred延迟执行。 - 如果需要在场景切换时保留玩家数据(如手里剑数量、生命值),建议将这些数据放在自动加载的单例中,而非每个关卡的GameManager里,避免切换场景时数据丢失。
内容的提问来源于stack exchange,提问作者BLAZE GAMING
相关产品推荐
相关产品推荐

