How to load a scene into a tree

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

Hi all,
Recently i have been working on a project in which i require to plant a crop i have this crop saved in a separate script which inherits a base crop script, then on a Autoload script which I’ve named Global, i have all the different types of plants. When the player presses on a button in the Main scene they swap the selectedplant variable to the type of plant the button represents, in the example of the code below there are two buttons one for Testplant1 and Testplant2. When the player presses the plant button the selectedplant variable is then put into the load() function and converted into a file destination, these then equal the same as the files which are under a separate folder called Plants.

func _on_Button1_pressed() -> void:
print("res://Plants/" + str(Global.selected_plant) + ".tscn")
Global.selected_plant = Global.Testplant1



func _on_Button2_pressed() -> void:
	Global.selected_plant = Global.Testplant2


func _on_PlantCropButton_pressed() -> void:
	load("res://" + str(Global.selected_plant) + ".tscn")

I thought i was being pretty ingenious with this method so hopefully someone can help make me understand where i went wrong. Thankyou so much for your time, if you need anything or want me to explain anything further please do ask!

Thanks for your time.

You’ve explained what you want to happen, but not what is happening instead. Do you get any errors? Does it run but not as expected?

moniker | 2021-05-02 16:37

Also see here for how to instance nodes at runtime: Resources — Godot Engine (3.3) documentation in English

moniker | 2021-05-02 16:37

:bust_in_silhouette: Reply From: moniker

From your _on_PlantCropButton_pressed() function it looks like you’re just loading the resource but now instancing it. To add a new node to the tree you need to:

  1. Have a loaded resource/packed scene (which you have)
  2. Instance it.
  3. Give it a parent node.

Try something like (untested, may be typos):

var cropScene = load("res://" + str(Global.selected_plant) + ".tscn") #reference to the loaded resource
var newCrop = cropScene.instance() #creates a new node
get_parent().add_child(newCrop) #this adds the new crop as a child of the current node
1 Like
:bust_in_silhouette: Reply From: VincePrinceKing

2 things i can guess without seeing the Global.singleton :

if the values Global.Testplant1, Global.Testplant2 arent Strings that could be the issue.

the other thing is load(“res://” + str(Global.selected_plant) + “.tscn”) does nothing by itself.

this could would load scene1.tscn or scene2.tscn if pressed.

var string_variable:String="scene1" ## lets set some default so we dont cause crashes

func _on_Button2_pressed():
	string_variable="scene1"

func _on_Button_pressed():
	string_variable="scene2"

func _on_Button3_pressed():
	var scene_trs =load("res://"+string_variable+".tscn")
	var scene=scene_trs.instance()
	add_child(scene)

is neccesarry to actually make an instance. load() and preload() and add the scene as a child to some existing node. Otherwise it wont show up.

an analogy:
-load(), preload() is like looking up the blueprint of the legohouse you wanna build.
-instance() is buying one of the boxes that include all parts you need to buy said house, if you instance() at some point later again you will build the exact same looking legohouse later again.
-add_child() is the putting the pices together and setting it into your cupboard (assuming cupbard would be the node where we add it) where you can finally see it and interact with it. for example put lego figurines into it, paint it’s walls etc.