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
export(NodePath) var n     # assigned in editor - cool stuff
func _ready():
    n = get_node(n)        # cause nothing better to do in life

My guess is it's over 90% of uses of NodePath... is there a way to get the node and keep it in one line? :)

in Engine by (28 points)

3 Answers

+2 votes

Do you mean something like?

extends Node2D

export (NodePath) var path setget set_path
var node_reference

func set_path(val):
    path = val
    node_reference = get_node(val)
by (5,286 points)

Thanks for pointing me into tools but it's even more work this way i think.

Would a tool iterating over all children and linking references in editor work? I need them linked in-game...

What are you trying to accomplish?

I assumed you wanted tool mode, since you're doing things with export vars, and those are accessed in the editor.

Trying to pick a node via editor, but not having to type "get_node()" for every export i use. Looking for "once and for all" solution.

This is what i googled on this so far...

Actually discovered that even calling get_node() on provided NodePath creates problems on ready when one node needs nodes in another node that gets ready later.

Abandoning "export(NodePath)"s for now. Would be great if it worked though.

Using just var a = getnode("path") doesn't work either as it demands to be onready in my case. Next solution: another node on the bottom of the list to connect other nodes and call their init functions... which can't be "_ready" now.

Ok, my results might've been obscured by missing "_" in front of "ready" in one place...

It's hard to say what you're working on there.

If you're having some issues with timing, you can use call_deferred to delay things a frame.

That can get kind of messy, alternatively you can try and create a central piece of logic that executes at the root node. When that one is ready you can be assured all child nodes are ready as well. Since ready works backwards up the tree.

Another thing you have to be mindful of with export variables in tool mode, is that when the scene initializes, the editor will take the saved value for that variable (from the scene file), and set it with the setter function. This will also execute any code you have there. So if you have code that depends on the state being ready, you will run into an error, because this code will execute at initialization.

You can wrap a setter like I have below, if you need to prevent conditional code from running in tool mode:

# For things that need to be in the tree
func set_export_var(val):
    my_export_var = val

        # Do stuff

# For things that need to be ready
onready var is_ready = true

func set_export_var = val
    my_export_var = val

        # Do stuff

Thanks for the info, i was missing some of this :)

Was trying to organise everything a bit better and tried some approaches and exports. Settled on a solution of parent node linking child nodes with each other. Some of them need others on their ready function and in general they need others while processing. Changed ready to custom defined lateReady wherever there was an error which is executed by parent after other nodes are connected. Seems to be working so far.

You're welcome. I've found in my work with tool mode, relying specifically on the init, enter, ready, exit, can be limiting. It's best to do what you're saying, and create a custom method of your own, and have it called only when you know the timing and conditions you need are met.

In the editing process, you're not likely to notice a few lost frames on loading, if something has to wait to make sure the scene tree is in the state you want it to be in.

0 votes

This is an old question, but this is what I've been doing in case anyone finds it useful.

export(NodePath) var node_path
onready var node_ref = get_node(node_path)

This way, you don't need a _ready method if you won't be using it for something else.

by (14 points)
+1 vote

I was trying to find out how to do this in Godot 4 and came across this question. It is old but no answer has a one-line solution, so here it is:

export(NodePath) onready var n = get_node(n)  # You can use type casting for code completion
by (62 points)
edited by

Thank a ton, this has been so annoying. I hadn't figured out this oneliner.

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.