Load a scene into another scene while keeping the first scene paused

Godot Version

4.6

Question

Hello everyone

I’m currently struggling with something that is seemingly simple but for the love of me, I don’t know how to pull this off. And since the main idea of my game lies on that, well, it’s pretty important that I can make it work.

Basically, what I want to do is to have a scene, with back-and-forth transitions with scenes in it. It’s a 2D game.

Let’s take an example of a scene in a work office, and you’re facing the computer. I want at some points to zoom into the computer screen, and change the scene for a mini-game in it. After beating (or losing) the mini-game, the main scene (Work Office) state needs to be able to be resumed, with all the states it had before transitioning and the music used in the main scene should be resumed from when it stopped.

I’m mostly confused on what functions should I use, and what architecture my scene tree should look like: a main scene loading dynamically the requested child scenes? The Work Office scene loading and destroying the mini-game? I’m a bit lost.

Seems pretty simple, but since I’m starting with Godot, I’m struggling a bit to pull this off.

Thank you for your help!

For example, to add some other scene to the current_scene:

func add_child_to_current_scene(filepath: String) -> Node:
    # TODO: add error checks
    var packed_scene: PackedScene = load(filepath)
    var instance: Node = packed_scene.instantiate()
    get_tree().current_scene.add_child(instance)
    return instance

Zooming the view is just changing the properties of the camera.

To pause just a part of your tree requires a bit more effort, but is possible. For example, to stop Godot’s processing in a branch (assuming Node are all set to PROCESS_MODE_INHERIT):

const PROCESS_METHODS: Array[String] = [
	"set_process",
	"set_physics_process",
	"set_process_input",
	"set_process_unhandled_input",
	"set_process_shortcut_input",
	"set_process_unhandled_key_input",
]

func pause_branch(node: Node) -> void:
    node.set_block_signals(true)
    for method: String in PROCESS_METHODS:
        node.call(method, false)

func unpause_branch(node: Node) -> void:
    node.set_block_signals(false)
    for method: String in PROCESS_METHODS:
        node.call(method, true)

Note this doesn’t stop all code in the branch from running because other ways of calling code in the nodes will still work–you’ll have to design your code with that in mind.

If it’s necessary to call the various PROCESS_METHODS on each node in the branch, use propagate_call instead of call.