@tool class_name EventBinder extends Node @export_group("Updater", "updater") @export var updater_event := &"" @export_enum("enabler", "disabler", "shower", "hider") var updater_mode := "enabler" # 仅对 canvas item 生效; <=0 时无 ease @export var updater_ease_duration := 1.0 @export_enum("include", "exclude") var updater_stage_mode := "include" @export var updater_stages: Array[int] = [1] @export_group("Trigger", "trigger") @export var trigger_event := &"" @export_tool_button("AutoDetectMode") var trigger_auto_detect_mode := _auto_detect_mode @export_enum("none", "interacted", "triggered", "played") var trigger_mode := "none" @export_range(0, 10000, 1) var trigger_stage := 1 @export var trigger_set_stage_if_greater := true var _local_enable_event_stage := 0 func _ready() -> void: if Engine.is_editor_hint(): return var parent = get_parent() if not updater_event.is_empty(): if not parent: printerr("[EventBinder] bind_enable is true but parent is null. path: %s" % get_path()) return _local_enable_event_stage = EventManager.get_stage(updater_event) _update_binding_state(_local_enable_event_stage) EventManager.stage_updated.connect(_on_global_stage_updated) if not trigger_event.is_empty(): # connect trigger_mode signal if trigger_mode == "interacted": parent.interacted.connect(_on_happened) elif trigger_mode == "triggered": parent.triggered.connect(_on_happened) elif trigger_mode == "played": parent.played.connect(_on_happened) func _on_happened() -> void: if trigger_set_stage_if_greater: var updated = EventManager.set_stage_if_greater(trigger_event, trigger_stage) if not updated: print( ( "[EventBinder] _on_happened not updated, event: %s, stage: %s" % [trigger_event, EventManager.get_stage(trigger_event)] ) ) else: EventManager.set_stage(trigger_event, trigger_stage) func _on_global_stage_updated(e: StringName, s: int): if e == updater_event: _local_enable_event_stage = s _update_binding_state(s) func _update_binding_state(stage: int): var parent = get_parent() if not parent: printerr("[EventBinder] _update_updater_visibility parent is null. path: %s" % get_path()) return # check stage in updater_stages var updater_status = false if updater_stage_mode == "exclude": updater_status = not stage in updater_stages elif updater_stage_mode == "include": updater_status = stage in updater_stages # check updater_mode if updater_mode == "enabler": parent.enabled = updater_status elif updater_mode == "disabler": parent.enabled = not updater_status elif updater_mode == "shower": _toggle_parent_visibility_with_ease(parent, updater_status) elif updater_mode == "hider": _toggle_parent_visibility_with_ease(parent, not updater_status) func _toggle_parent_visibility_with_ease(parent, show: bool): if parent is CanvasItem: parent.visible = true parent.modulate.a = 0.0 if show else 1.0 var target_a = 1.0 if show else 0.0 var tween = create_tween() tween.tween_property(parent, "modulate:a", target_a, updater_ease_duration) if not show: tween.tween_callback(parent.hide) func _auto_detect_mode(): # TODO 统一interacted played picked var parent = get_parent() if not parent: printerr("[EventBinder] _auto_detect_mode parent is null. path: %s" % get_path()) if parent.has_signal("interacted"): trigger_mode = "interacted" elif parent.has_signal("triggered"): trigger_mode = "triggered" elif parent.has_signal("played"): trigger_mode = "played" else: printerr("[EventBinder] _auto_detect_mode cannot detect trigger mode. path:", get_path())