@tool extends Marker2D class_name SignSnapper signal arrived @export var release_player_on_arrived := true # 仅使用 x 坐标;否则也用 y 进行 walk to @export var use_x_only := true # x 左右有效范围 @export_range(0.0, 20.0, 0.1) var radius := 0.0 # arrived 延时 @export_range(0.0, 10.0, 0.1) var delay_arrived := 0.0 @export_tool_button("debug 检查玩家触发位置") var debug_check_player_pos = _debug_check_player_pos var detacted_sign: Sign # 玩家在和 sign 交互时,如果读到节点中有 SignSnapper,则移动到该位置(x 对齐) func _ready(): if not get_parent(): return for c in get_parent().get_children(): if c is Sign: detacted_sign = c break if not detacted_sign and Engine.is_editor_hint(): printerr("SignSnapper must have a Sign sibling node!") if not Engine.is_editor_hint(): detacted_sign.interacted.connect(_on_interacted) func _on_interacted(): if not detacted_sign: return var player = SceneManager.get_player() var target_pos = global_position if use_x_only: target_pos.y = player.global_position.y var tween = player.walk_to(target_pos, release_player_on_arrived) if delay_arrived > 0: tween.tween_interval(delay_arrived) tween.tween_callback(arrived.emit) func _debug_check_player_pos(): var ground = EditorInterface.get_edited_scene_root().get_node("Ground") as Ground2D if use_x_only: ground.replace_player_to_portal = true var player = ground.player if radius > 0: var player_x = player.global_position.x if absf(player_x - global_position.x) > radius: # clamp in range if player_x < global_position.x: player.global_position.x = global_position.x - radius else: player.global_position.x = global_position.x + radius else: player.global_position.x = global_position.x if not use_x_only: player.global_position.y = global_position.y