2D: How To Enter And Exit Between Scenes From The Same Scene

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By AdamSmif

Hey All,

Right now I use an Area2D node with the following code to allow me to switch between scenes whenever the player collides with the Area2D node

WorldComplete.gd

extends Area2D

export(String, FILE, “*.tscn”) var next_world_scene

func _physics_process(_delta):
var bodies = get_overlapping_bodies()

print(bodies)

for body in bodies:
	if body.name == "Player":
		emit_signal("level_complete")
		$NextLevelSound.play()
		get_tree().change_scene(next_world_scene)

This all works great but the big issue I have is that for my hub world, there are multiple scenes to transition to so when you go about different scenes, you don’t leave the same way you came out of.

Basically imagine playing Link To The Past, but every time you left a dungeon to go to Hyrule Field, you always spawned at the center of the map rather than by the exit you just came out of.

I’m going to assume AutoLoads is going to be my best bet but not sure the best way to go about this. Any help would be sincerely appreciated.

Take care,

:bust_in_silhouette: Reply From: exuin

Right, you can use an autoload for this. On each Area2D you can store the position that you want the player to appear at in the next scene. When the player enters the Area2D, send that data to the autoload. Then, after the scene change, you can set the player’s position using that data.

Appreciated it exulun,

So when my player collides with the Area2D, it emits the “level_complete” signal so what should I have in my autoload to store? My brain is pretty jumbled trying to think of a smart solution but right now I’m thinking have in the autoload code something like this

var destination

func _ready():
destination = get_node(“next_scene”).get_global_position()

Again, can’t stress enough that I’ve been over thinking this but once this is setup that will be a huge step in quality for my game. Would love to hear your thoughts.

Thank you!

AdamSmif | 2021-04-22 04:28

Well, you could just access the autoload directly and set the destination variable when the player hits the Area2D. Like,

Global.destination = Vector2(some position here)

exuin | 2021-04-22 05:10

So on my autoload script would I have all the different Vector2 positions stored in the autoload? Trying to visualize how I should go about this. Appreciate your help.

AdamSmif | 2021-05-14 16:36

Not necessarily. You could store only the current Vector2 position that you want the player to appear at in the next scene and change that whenever the scene is changed.

exuin | 2021-05-14 16:38

So my exit script would have this

extends Area2D

func _physics_process(_delta):
var bodies = get_overlapping_bodies()
for body in bodies:
if body.name == “Player” or “GolfCartPlayer” or “CYOAPlayer” or “PlayerAutoRun” or “PlayerSkateBoard” or “PogostickPlayer” or “Submarine”:
$NextLevelSound.play()
Global.destination = Vector2(25, 50)

Is Global the name of my autoload? How would I transfer that data over to the autoload?

AdamSmif | 2021-05-14 16:46

Well first off, there’s no need to check for overlapping bodies every frame. Just check whenever a new bodies enters using signals.

Second, that if statement doesn’t work. You will need to write body.name == “string” for every string you want to compare it to. Otherwise it will only convert the string itself to a bool, and every non-empty string evaluates to true, so that if statement will always evaluate to true. Consider putting all the names into an array and using the in keyword, using collision layers, or groups.

Third, yes Global is the name of your autoload. Since you can access those directly you’ve already transferred the data over by setting the destination variable.

exuin | 2021-05-14 17:19