2025-06-24 19:36:07 +00:00
|
|
|
|
@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
|