How to access nodes best practise

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

Short introduction: I started learning Godot by making simple existing games. I made a Flappy Bird clone and it was ugly, but worked. I knew it could be a lot better, so I looked up a (pretty excellent) tutorial on Youtube and got the reference project through the Godot library. It’s an excellent Flappy Bird clone, but the teacher loses me a bit when getting nodes.

In the tutorial you access a method on a camera2D node in the main tree, from a Scene which isn’t on the main tree. To get this to work, he uses a clever utilities node, but the code comes down to this:

onready var camera = get_tree().get_root().get_child(get_tree().get_root().get_child_count()-1).get_node("Camera2D")

I’ve tried many other ways, but failed. I tried to look up a better solution on here and in the official documentation, but didn’t find any. I also think this may not be best practise in light of decoupling…But maybe I don’t fully understand this as I’m still a novice/intermediate programmer.

Anyway: can anyone point me in the right direction to fully understand this and provide an example of how the above code could work, but in a less roundabout/best practise way?

:bust_in_silhouette: Reply From: Cire_arievilo1

I’m not very good at explaining things, but I found this informations interesting:

UNDERSTANDING NODE PATHS

Godot Tutorial - How to get Node in other Scene

you can also drag your Camera 2D node and drop it into the code with the CTRL button pressed. this is only possible in godot 3.5 and up.

and finally an example:

Onready var camera = get_node("/root/Game/Camera2D")

where “Game” is the name of your main scene.

Thank you! Your example line actually works. I swear I tried all different kinds of combinations of this line…I guess I maybe missed a slash or was overthinking it. I’ll make sure to read up on this via the link you provided.

Dragging the node in with CTRL is a great QOL addition. In this scenario it didn’t work though. I think maybe this only works if it’s a child node. I get the following error:

Attempt to call function ‘example method’ in base ‘null instance’ on a null instance

Crispy | 2022-10-25 08:58

:bust_in_silhouette: Reply From: toxicvgl

I am wondering the reason you would like to access the Camera2D from outside of the main tree (or what it means). Isn’t your code searching in the main tree?

Anyway, the answer depends on how you use the method in Camera2D, I think.

  1. If it is a reaction of the Camera2D to some event in the game, then I may use signals.
  2. If the Camera2D is a child (which is not your case), then I may use $Camera2D, or write a line export(NodePath) onready var camera = get_node(camera) as Camera2D, then drag the Camera2D in the scene and drop on the inspector.
  3. If they are not in a parent-child relation, then it may be a task of the root node. On the root node, get Camera2D and the node X in problem by the previous method. Then, write a line like X.camera = Camera2D (this code is conceptual).

These are not the best ways because Cire_arievilo1’s method is much simpler. But I think these are good in terms of decoupling.

It was meant to let spawned groundtiles know when they’re offscreen, ready to be freed. After the comments here I looked for another way and ended up just using a visibilitynotifier to tell the groundtile when it is offscreen. Way simpler and no dependencies. I do understand node paths better now, so it wasn’t for nothing!

Crispy | 2022-10-25 14:56