Changing a scene and adding player to scene FROM previous scene.

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

I have a global variable of the instance of my player (autoload). I add him into my “Village” scene. There are houses you can (hopefully lol) go into. When I go into the house it changes the scene (using the change scene “goto_scene()” from the API. However i’ve been having issues with it. Most were solved thanks to an excellent person on reddit, but now my issue is my player is being added to the root because it can’t find the newly added scene.

My village scene has an area 2D to trigger the scene change:

func _on_Area2D_body_entered(body):	
	remove_child($Player)	
	Globals.goto_scene("res://Scenes/House1.tscn")	
	get_tree().get_root().add_child(Globals.Player)		
	Globals.Player.position = Vector2(245, 245)

I know why it goes to the root (as thats what the code says) but I can’t find a way to add it to my Next scene (House1) from the function in Village1. Anything else i’ve tried causes a lot of problems… this at least gets the player on the screen in the right location… just not IN (or a child) the house scene (hes underneath it because of his location in the scene tree.

I’ve also had issues adding the player and position on the ready()…Trying to add to the root then call_deferred a function that adds it back… lol amongst many many many other things. I’ve read the API, looked for videos… found great examples of similar things on here… but I can’t quite get it to work for what i’m trying.

To further paint the picture of what i’m needing. I’m making a top down RPG (old zelda or stardew valley -like) I just need a way to transition between my “maps/levels/world”. Walk into a shop… walk out of a shop… walk into a cave… walk out of a cave. I’ve ALMOST got it… I just can’t get the last part of positioning my player where he needs to be from the scene i’m leaving. I’m all ears for fixing/changing/completely redoing this as long as I can achieve that.

What does your Globals.goto_scene-method do? Is there any difference between $Player and Globals.Player?

njamster | 2020-04-13 22:21

As for my $Player and Globals.Player. There shouldn’t be. Globals.Player is just a Global Instance of my player scene, I used that to add my character to the scene, It just seems way easier to do that.

Here is my goto_scene()

func goto_scene(path):
# This function will usually be called from a signal callback,
# or some other function in the current scene.
# Deleting the current scene at this point is
# a bad idea, because it may still be executing code.
# This will result in a crash or unexpected behavior.

# The solution is to defer the load to a later time, when
# we can be sure that no code from the current scene is running:

call_deferred("_deferred_goto_scene", path)

func _deferred_goto_scene(path):
	# It is now safe to remove the current scene
	current_scene.free()
	print("FREE'd")
	# Load the new scene.
	var s = ResourceLoader.load(path)

	# Instance the new scene.
	current_scene = s.instance()

	# Add it to the active scene, as child of root.
	get_tree().get_root().add_child(current_scene)

	# Optionally, to make it compatible with the SceneTree.change_scene() API.
	get_tree().set_current_scene(current_scene)
	print("CURRENTSCENECHANGE")

Aireek | 2020-04-13 22:34

Have you tried adding

current_scene.add_child(Globals.Player)

after this line in your deferred_goto_scene-method?

get_tree().get_root().add_child(current_scene)

njamster | 2020-04-13 22:41

My god… it works. Perfectly. I tried to do that IN my village scene on the Area2D entered script… WHY did I not think to just add this to my change scene method. I spent so many hours trying to figure this out and I had the right idea… just didn’t think to put it in the right spot. My dude thank you! I feel so silly now lol

Aireek | 2020-04-13 22:47

:bust_in_silhouette: Reply From: Aireek

Have you tried adding

current_scene.add_child(Globals.Player)

after this line in your deferred_goto_scene-method?

get_tree().get_root().add_child(current_scene)

answer by njamster