I don’t have a problem but just wondering why I can’t refer to unique names in
an instantiated scene.
Here’s what I have:
I have a game with a scene of a bottle of green slime ihat the player can pick up and break.
When the bottle breaks I instanatiate a scene of GREEN_SLIME_PUDDLE into the level.
I use code similar to the following to instantiate it.
@onready var scene_name = preload(“res://Scenes/scene_name.tscn”)
var instance_name = scene_name.instantiate()
add_child(instance_name)
This slime affects the player and in other scenes I can refer to the player scene as unique %Player.
Every other scene in the game I can use the unique name for the player but
in the instantiated scene I have to use get_parent().get_node(“Player”).
This is fine and it works just as good but I’m wondering why does it give an
error saying %Player is a null instance. If I add the scene directly into the level
scene %Player gets the node just fine. It’s only when instantiated from code that
the null instance error occurs.
Just curious as to why this is as I can’t find a logical explanation. Maybe
understanding why this occurs will help me design code better in the future.
Thanks!
Edit:
Oh, and if you are wondering if the scenes is being added to the correct level scene then the answer is Yes. I checked that in the remote tab.
name ambiguity, imagine a scenario where you have two objects dynamically instantiated that were designated unique with the same name, which instance would %node_name be referring too?
Also i believe its a scene concept only. There is no programmatic way to make something unique from code. You select the node in the editor and make it unique to the scene. If you dynamically instantiate a scene, how is it made unique? Ultimately it doesnt as you have seen.
You should still be able to do
instantiated_scene.get_node(“%unique_node”) as the instantiated scene “namespaces” its unique nodes by its root node.
I didn’t make myself clear enough in my explanation. Sorry for that.
The instantiated scene is not the unique named one. It has trouble ‘getting’ a unique named scene through it’s script.
I have a LEVEL_01 scene with other scenes inside and one of them is the %Player scene.
I also have Item scenes inside the level as siblings to Player.
Those siblings added into the level scene through the editor have scripts attached to them and can find %Player just fine.
But when the exact same Item scene is instantiated via code (as above) it doesn’t find %Player and tells me %Player is a null instance even though it is in the LEVEL_01 scene and set as unique.
It is the exact same Item scene with the same script added two different ways to the same Level scene but when added through the editor it can find unique names and when added through code cannot.
I hope that made more sense.
I do appreciate the response.
The scope of unique names is the scene to which the node belongs to. So child scenes cannot see the unique names in the parent scene. If you add a node to the parent scene and assign the script to it, the script now is in scope of the parent - therefore it can see the unique names.
Yes, this is also possible - the get_child(0) basically changes the “search scope” to the child scene and therefore the unique names of the child can be accessed. This is also explained in the docs:
If a script has access to a node in another scene, it can call get_node() on that node to get scene unique nodes from that node’s scene.
“Has access” is equivalent to get_child(0) in your example.
Thanks guys, some of the nuances of how nodes correspond to each other still elude me but I did get it working by using the get_child() method. It works and I can reuse the same scenes for all my level scenes throughout the game since I’m keeping the same structure for all the levels.
get_child is not necessary i was just to lazy to make a global reference variable after the fact. As long as you have a reference to the base node of a scene you can use base_scene_node.get_node(“%”) to get its unique nodes.
That sounds better because I was getting the root then getting the child. If i can get the base_scene then get %Player that sounds like a better solution.
Like I said, it does work but I will play around with your suggestion to learn how to use them better in the future.
Thanks
Edit:
Oh, and I do have an autoload Global scene/script for adding sounds but I didn’t find out about creating them until I had already gotten in the weeds into my game code. I did move scenes I had copied over and over from level to level into the Global scene like my input manager and the saveprogress node and pause menu. I should have put the player in there but I had not tried it yet so I’m pretty sure that would have helped my case too. lol I’m a newby but i’m learning!
This project is my first and was intended purely as a learning process but it is shaping up to be a decent game imho so I keep adding to it.