75 lines
1.8 KiB
GDScript3
75 lines
1.8 KiB
GDScript3
|
|
@tool
|
||
|
|
class_name SceneManager
|
||
|
|
extends Node
|
||
|
|
|
||
|
|
@export var MainNodes: Array[Node]
|
||
|
|
@export var GameView: Node
|
||
|
|
@export var TransitionNode: Node
|
||
|
|
|
||
|
|
func _enter_tree() -> void:
|
||
|
|
check()
|
||
|
|
|
||
|
|
func _ready() -> void:
|
||
|
|
if !Engine.is_editor_hint():
|
||
|
|
add_to_group("SceneManager")
|
||
|
|
get_tree().node_removed.connect(check)
|
||
|
|
|
||
|
|
# =========================
|
||
|
|
# 对外 API
|
||
|
|
# =========================
|
||
|
|
static func change(scene_path: String) -> void:
|
||
|
|
var mgr := get_instance()
|
||
|
|
if mgr:
|
||
|
|
mgr._change(scene_path)
|
||
|
|
else:
|
||
|
|
push_error("SceneManager not found in scene tree")
|
||
|
|
|
||
|
|
# =========================
|
||
|
|
# 内部逻辑
|
||
|
|
# =========================
|
||
|
|
func _change(scene_path: String) -> void:
|
||
|
|
if GameView == null:
|
||
|
|
push_error("SceneManager: GameView is null")
|
||
|
|
return
|
||
|
|
|
||
|
|
# 清空旧场景
|
||
|
|
for child in GameView.get_children():
|
||
|
|
child.queue_free()
|
||
|
|
|
||
|
|
# 加载新场景
|
||
|
|
var packed: PackedScene = load(scene_path)
|
||
|
|
if packed == null:
|
||
|
|
push_error("Failed to load scene: %s" % scene_path)
|
||
|
|
return
|
||
|
|
|
||
|
|
var instance := packed.instantiate()
|
||
|
|
GameView.add_child(instance)
|
||
|
|
|
||
|
|
print_debug("SceneManager: Changed scene to ", scene_path)
|
||
|
|
|
||
|
|
# =========================
|
||
|
|
# 结构检查 / 自修复
|
||
|
|
# =========================
|
||
|
|
func check(node: Node = null) -> void:
|
||
|
|
if TransitionNode == node:
|
||
|
|
TransitionNode = null
|
||
|
|
|
||
|
|
var tr := find_child("Transition")
|
||
|
|
if tr != null:
|
||
|
|
if TransitionNode == null:
|
||
|
|
TransitionNode = tr
|
||
|
|
else:
|
||
|
|
if TransitionNode == null:
|
||
|
|
var transition := Control.new()
|
||
|
|
transition.name = "Transition"
|
||
|
|
add_child.call_deferred(transition)
|
||
|
|
transition.set_owner.call_deferred(self)
|
||
|
|
TransitionNode = transition
|
||
|
|
|
||
|
|
# =========================
|
||
|
|
# 工具
|
||
|
|
# =========================
|
||
|
|
static func get_instance() -> SceneManager:
|
||
|
|
var tree := Engine.get_main_loop() as SceneTree
|
||
|
|
return tree.get_first_node_in_group("SceneManager") as SceneManager
|