That script is attached to a CanvasLayer node with a ProgressBar called HealthBar. And yet, when running the scene, it will throw an error:
This is because there’s actually a spelling error; instead of HealthBar, the node is called HeatlhBar. It’s easy to miss, and we all occasionally make spelling errors.
Since you can easily drag nodes into scripts and create @onready references by holding down CTRL before releasing the mouse button, another version of the script might look like this:
With the script in place, the
health_bar
node can be assigned via the Inspector:
Initially, this may seem like a bit more work, to first have to declare it and then assign it, but it is the most reliable, flexible solution to referencing nodes. You can even rename the HealthBar node, and the
health_bar
node reference will update accordingly.
This approach is especially helpful when building complex user interfaces where you might rearrange nodes a lot. One concern is having a long list of export properties, some of which are actually used to reference nodes internal to the scene. That’s why I typically group them with
@export_group
:
That way, it’s clear in the inspector which properties are meant to be modified from outside the scene:
In addition, this separation between script and scene is a form of dependency injection that provides greater flexibility, so a script can be attached to a scene that has a completely different layout.
I’ve been using this technique almost exclusively, and rarely use
@onready
to assign a node reference via
$
or
get_node()
.
When I think of video games, I generally still think of an application that is downloaded and runs on the client. Technically, that’s still the case with web-based exports from Godot Engine, since the web browser has to download the files before being able to run them. I thought maybe I could just run the …
One of the benefits of working with Godot Engine is that GDScript allows one to operate high level. GDScript is dynamically typed, so not even variable types have to be specified, but I would strongly recommend using static typing wherever possible. It can help with performance but primarily adds clarity when trying to follow the …
I use an app called barrier. It allows you to share your mouse and keyboard with multiple devices. I use it, because I tend to have my laptop and Macbook sitting next to my PC, and it makes working across all devices very convenient. It’s a mix of a multi-monitor and multi-computer setup. Concept Your …
Normally I use OBS for screen recording, but there are cases where it makes sense to use Godot’s built-in movie writer that was recently announced. For example, if you have a slow PC or really demanding game, OBS will skip frames. It makes sense since OBS is just recording what’s on the screen in real …
Ditch @onready, use @export instead
Are you using @onready to reference nodes? There’s a better way!
Here’s a simple example of how many tutorials use @onready to reference nodes:
That script is attached to a CanvasLayer node with a ProgressBar called HealthBar. And yet, when running the scene, it will throw an error:
This is because there’s actually a spelling error; instead of HealthBar, the node is called HeatlhBar. It’s easy to miss, and we all occasionally make spelling errors.
Since you can easily drag nodes into scripts and create @onready references by holding down CTRL before releasing the mouse button, another version of the script might look like this:
Now it works, because it’s consistently misspelled.
If you now notice the misspelling in the Scene Tree and fix the node name, but don’t adjust the script, it’ll break again:
A better way is to use @export instead:
With the script in place, the
health_barnode can be assigned via the Inspector:Initially, this may seem like a bit more work, to first have to declare it and then assign it, but it is the most reliable, flexible solution to referencing nodes. You can even rename the HealthBar node, and the
health_barnode reference will update accordingly.This approach is especially helpful when building complex user interfaces where you might rearrange nodes a lot. One concern is having a long list of export properties, some of which are actually used to reference nodes internal to the scene. That’s why I typically group them with
@export_group:That way, it’s clear in the inspector which properties are meant to be modified from outside the scene:
In addition, this separation between script and scene is a form of dependency injection that provides greater flexibility, so a script can be attached to a scene that has a completely different layout.
I’ve been using this technique almost exclusively, and rarely use
@onreadyto assign a node reference via$orget_node().Related Posts
Quickly deploying Godot games on the web with Netlify
When I think of video games, I generally still think of an application that is downloaded and runs on the client. Technically, that’s still the case with web-based exports from Godot Engine, since the web browser has to download the files before being able to run them. I thought maybe I could just run the …
When not all strings are Strings. Detect bugs in your GDscript more easily with static typing
One of the benefits of working with Godot Engine is that GDScript allows one to operate high level. GDScript is dynamically typed, so not even variable types have to be specified, but I would strongly recommend using static typing wherever possible. It can help with performance but primarily adds clarity when trying to follow the …
Share your Computer’s Mouse and Keyboard with your Steam Deck
I use an app called barrier. It allows you to share your mouse and keyboard with multiple devices. I use it, because I tend to have my laptop and Macbook sitting next to my PC, and it makes working across all devices very convenient. It’s a mix of a multi-monitor and multi-computer setup. Concept Your …
Making videos for the web with Godot 4’s Movie Writer
Normally I use OBS for screen recording, but there are cases where it makes sense to use Godot’s built-in movie writer that was recently announced. For example, if you have a slow PC or really demanding game, OBS will skip frames. It makes sense since OBS is just recording what’s on the screen in real …