为Animator的animation_finished信号绑定多Area2D后场景切换异常的解决咨询
问题分析与解决方案
问题根源
你遇到的核心问题是所有Area2D都绑定了同一个Animator的animation_finished信号,导致过渡动画结束时,四个Area2D的_on_transition_animation_finished回调会依次执行,最终只有最后一次场景切换生效;同时Autoload的目标信息会被多个回调反复覆盖,也是因为所有绑定的脚本都在修改它。
方案一:触发过渡的Area2D临时绑定信号(推荐)
不让所有Area2D提前绑定信号,只在玩家进入并触发过渡时,让当前Area2D临时监听动画结束信号,完成切换后立即解除绑定,避免其他Area2D干扰。
修改后的Area2D脚本:
extends Area2D var entered = false @export var room = "" var animation_playing = false @export var xPosition = 0 @export var yPosition = 0 var player var transition_animator = null # 缓存过渡动画节点 func _on_body_entered(body: PhysicsBody2D): entered = true player = body # 获取主场景的过渡动画节点 transition_animator = get_parent().$Transition func _on_body_exited(body): entered = false # 退出时解除信号绑定,避免残留 if transition_animator != null: transition_animator.animation_finished.disconnect(_on_transition_animation_finished) animation_playing = false func _process(delta): if entered == true and animation_playing == false: var scene = get_parent() if scene.has_method("playFadeOutTransition"): animation_playing = true # 临时绑定信号到当前Area2D的回调 transition_animator.animation_finished.connect(_on_transition_animation_finished) scene.playFadeOutTransition() func _on_transition_animation_finished(anim_name): if anim_name == "fade_out": var autoload = get_node("/root/Global") autoload.playerStartPosition = Vector2(xPosition, yPosition) get_tree().change_scene_to_file(room) # 动画结束后立即解除信号绑定 transition_animator.animation_finished.disconnect(_on_transition_animation_finished) animation_playing = false
方案二:主场景统一处理场景切换
让主场景负责监听动画结束信号,Area2D只负责将目标房间和位置写入Autoload,由主场景在动画结束后执行切换,避免多脚本同时触发逻辑。
1. 修改Area2D脚本
extends Area2D var entered = false @export var room = "" var animation_playing = false @export var xPosition = 0 @export var yPosition = 0 var player func _on_body_entered(body: PhysicsBody2D): entered = true player = body func _on_body_exited(body): entered = false animation_playing = false func _process(delta): if entered == true and animation_playing == false: var scene = get_parent() if scene.has_method("playFadeOutTransition"): animation_playing = true # 将目标信息写入Autoload var autoload = get_node("/root/Global") autoload.targetRoom = room autoload.playerStartPosition = Vector2(xPosition, yPosition) scene.playFadeOutTransition()
2. 修改主场景脚本
extends Node2D @export var fadeIn = false func _ready(): $Transition/ColorRect.visible = false if fadeIn == true: $Transition/ColorRect.visible = true playFadeInTransition() # 主场景自身监听过渡动画的结束信号 $Transition.animation_finished.connect(_on_transition_animation_finished) func playFadeOutTransition(): $Transition.play("fade_out") func playFadeInTransition(): $Transition.play("fade_in") func _on_transition_animation_finished(anim_name): $Transition/ColorRect.visible = false if anim_name == "fade_out": var autoload = get_node("/root/Global") # 主场景统一执行场景切换 get_tree().change_scene_to_file(autoload.targetRoom)
3. 补充Autoload(Global)变量
确保你的Autoload脚本中添加对应的变量:
extends Node var playerStartPosition = Vector2.ZERO var targetRoom = ""
内容的提问来源于stack exchange,提问作者Todu
相关产品推荐
相关产品推荐

