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

Godot 4.1中信号重复触发问题求助

状态机信号触发两次问题排查求助

我确定这只是“看起来”触发两次,肯定有遗漏的明显点,但已经排查很久毫无头绪。

为解决场景过渡问题并控制信号逻辑,我实现了一个基础有限状态机(FSM),相关代码如下:

GameStateMachine 代码

class_name GameStateMachine
extends Node

@export var initial_state: GameState

var current_state: GameState
var _states: Dictionary = {}

func _ready() -> void:
    for c in get_children():
        if c is GameState:
            _states[c.name.to_lower()] = c
            c.transitioning.connect(_on_state_transition)
            
    if initial_state:
        current_state = initial_state
        initial_state.enter()

func _process(delta: float) -> void:
    if current_state:
        current_state.update(delta)

func _physics_process(delta: float) -> void:
    if current_state:
        current_state.physics_update(delta)

func _on_state_transition(state: GameState, new_state_identifier: String) -> void:
    print("transition signal from: %s" % state.name)
    #SceneTransition.fade_to_black()
    
    if state != current_state:
        print("not in current state, odd")
        return
    
    print_debug("Switching State: %s to %s" % [state.name, new_state_identifier])
    var new_state = _states.get(new_state_identifier.to_lower())
    if not new_state:
        print("Unknown state: %s" % new_state_identifier)
        return

    if current_state:
        current_state.exit()
    current_state = new_state
    new_state.enter()

GameState 基类代码

class_name GameState
extends Node

signal transitioning

func enter() -> void:
    pass

func exit() -> void:
    pass

func update(delta: float) -> void:
    pass

func physics_update(delta: float) -> void:
    pass

Initial 状态代码

extends GameState

func enter() -> void:
    transitioning.emit(self, "title")

Title 状态代码

extends GameState

const TITLE_SCENE: String = "res://game/main_scenes/title_screen/title_screen.tscn"

func enter() -> void:
    ResourceLoader.load_threaded_request(TITLE_SCENE, "", true)
    get_tree().change_scene_to_packed(ResourceLoader.load_threaded_get(TITLE_SCENE))

运行后日志显示信号被触发两次:

transition signal from: Initial
Switching State: Initial to title
   At: res://game/services/game_engine_core/state_machine.gd:35:_on_state_transition()
transition signal from: Initial
Switching State: Initial to title
   At: res://game/services/game_engine_core/state_machine.gd:35:_on_state_transition()

我无法理解信号为何触发两次。该FSM作为自动加载的根节点“Game”的子节点运行,使用Godot版本4.1.1,运行环境:Godot v4.1.1.stable - Windows 10.0.22621 - Vulkan (Compatibility) - NVIDIA GeForce RTX 4090 (NVIDIA; 31.0.15.3699) - 12th Gen Intel(R) Core(TM) i9-12900K (24 Threads)

恳请提供排查思路。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:10:23