I think you are running into a particular behavior to be aware of:
When Godot loads your scene, it creates nodes one by one and assigns their properties. Then later on, it is added to the tree.
When it creates TitleBar
, it assigns background_color
, but your code tries to access ColorRect
. However, it is possible that node wasn't created yet. It might not even be in the tree either.
When you have setters like this, you are only guaranteed to access properties of your own object. Any external object such as child nodes or the scene tree will be available only later (i.e your node may not necessarily be in the tree immediately). If they happen to work, it might be chance: objects creation order can vary unexpectedly, so code relying on that can break easily.
So to make this code more robust, you have to first check if the node is present, and if not, defer the assignment in _ready
because that's when you know the node will be there.
func _ready():
$ColorRect.color = background_color
func set_background_color(value):
background_color = value
if has_node("ColorRect"):
$ColorRect.color = background_color
UPDATE:
Here is the explanation why it worked in the video:
If you set a property to be the same value as its default value, Godot does not save it in the scene. Then it doesn't sets it when the scene loads.
When the guy tests the property in the editor, nodes are in the tree already so it's all fine and dandy. And then when he runs the game, it works because he had reset the value to default before, so it was not saved into the scene, so never set on load and no error for him. But I bet he will find that soon :p