51 lines
1.7 KiB
GDScript
51 lines
1.7 KiB
GDScript
class_name ScenePortal
|
|
extends Area2D
|
|
|
|
const InteractionAnchorUtil = preload("res://_Core/utils/InteractionAnchor.gd")
|
|
|
|
# ============================================================================
|
|
# ScenePortal.gd - 场景入口传送组件
|
|
# ============================================================================
|
|
# 提供轻量级场景跳转能力,用于广场、小区和个人空间之间的入口。
|
|
# ============================================================================
|
|
|
|
@export var targetSceneName: String = ""
|
|
@export var targetSpawnName: String = ""
|
|
@export var targetPosition: Vector2 = Vector2.ZERO
|
|
@export var interactionTitle: String = "进入"
|
|
@export var interactionDistance: float = 160.0
|
|
|
|
func _ready() -> void:
|
|
add_to_group("whaletown_interactable")
|
|
|
|
func _on_body_entered(body: Node2D) -> void:
|
|
return
|
|
|
|
func get_interaction_actions(player: Node2D) -> Array[Dictionary]:
|
|
var anchor_position: Vector2 = InteractionAnchorUtil.get_position(self)
|
|
var distance: float = anchor_position.distance_to(player.global_position)
|
|
if distance > interactionDistance:
|
|
return []
|
|
var label := interactionTitle.strip_edges()
|
|
if label.is_empty():
|
|
label = "进入 %s" % targetSceneName
|
|
return [{
|
|
"id": "portal:%s" % get_instance_id(),
|
|
"title": label,
|
|
"distance": distance,
|
|
"priority": 20,
|
|
"callback": Callable(self, "_change_scene"),
|
|
}]
|
|
|
|
func _change_scene() -> void:
|
|
if targetSceneName.is_empty():
|
|
push_warning("ScenePortal: targetSceneName is empty.")
|
|
return
|
|
|
|
if not targetSpawnName.is_empty():
|
|
SceneManager.set_next_spawn_name(targetSpawnName)
|
|
elif targetPosition != Vector2.ZERO:
|
|
SceneManager.set_next_scene_position(targetPosition)
|
|
|
|
SceneManager.change_scene(targetSceneName)
|