This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+1 vote

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?

Godot version v3.5 stable
in Engine by (16 points)

2 Answers

0 votes
Best answer

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


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.

by (286 points)
selected by

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

+1 vote

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 = 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.

by (46 points)
edited by

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!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.