-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscenes.gd
57 lines (48 loc) · 2.29 KB
/
scenes.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
extends Node
## emitted when `change_scene_to` is called, right after scene load is started
signal change_started(scene_path: String, params: Dictionary)
## emitted after the scene is loaded, but before it's `_ready` is called (ie. before it's added to the scene tree)
signal scene_loaded(scene: Node, params: Dictionary)
## emitted after the scene is fully loaded and completed it's `_ready` (after it's added to the scene tree)
signal scene_changed(scene: Node, params: Dictionary)
var _params: Dictionary = {}
@onready var _loader_mt = preload("res://addons/scenes/loader.gd").new()
## the current scene's root node
var current: Node = null
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
var cur_scene: Node = get_tree().current_scene
change_started.emit(cur_scene.scene_file_path, _params)
# if playing a specific scene
if ProjectSettings.get("application/run/main_scene") != cur_scene.scene_file_path:
if not cur_scene.is_node_ready(): await cur_scene.ready
scene_loaded.emit(cur_scene, _params)
current = cur_scene
scene_changed.emit(cur_scene, _params)
# fully sets the new scene up
func _set_new_scene(resource: PackedScene) -> void:
var current_scene = get_tree().current_scene
current_scene.queue_free()
await current_scene.tree_exited # wait for the current scene to be fully removed
var instanced_scn: Node = resource.instantiate() # triggers _init
scene_loaded.emit(instanced_scn, _params)
get_tree().root.add_child(instanced_scn) # triggers _ready
get_tree().current_scene = instanced_scn
current = instanced_scn
scene_changed.emit(instanced_scn, _params)
_params = {}
## this function will load a scene in a multithreaded manner (via `ResourceLoader`)
##
## returns the `scene_changed` signal to easily chain some code to run after the scene is changed.
## note that you should use `CONNECT_ONESHOT` while connecting anything to `scene_changed`
## (and any other signal) otherwise it will run every time a scene is changed.
func change_scene_to(path: String, params = {}) -> Signal:
_params = params
var maybe_resource = _loader_mt.load_resource(path)
change_started.emit(path, params)
if maybe_resource:
call_deferred("_set_new_scene", maybe_resource)
return scene_changed
else:
_loader_mt.resource_loaded.connect(_set_new_scene, CONNECT_ONE_SHOT)
return scene_changed