Script can no longer find child nodes after accidentally deleting, then loading

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

Hi, I’m new to Godot and just started doing tutorials to get used to the engine and GDScript. I’m currently following this ebook tutorial and it was working fine except for one thing. Using Godot3.2.

I accidentally cleared the script in my level scene (was a bit tired), but then attached a script again and loaded the existing one. Now it can’t find any of its own child nodes anymore. Getting null refs for all of them if I use the $ notation.

SceneTree :
root node - Node2D named Level

  • child node of type TileMap named Ground
  • child node of type TileMap named Walls
  • child node of type TileMap named Items
  • some other child nodes, instanced scenes, etc.

Script is attached to the parent node :
extends Node2D
onready var items = $Items

func _ready():
$Items.hide()
# other stuff

Debugger: attemp to call function ‘hide’ in base ‘null instance’ on a null instance
Errors : 0:00:0 get_node: Node not found: Items.

If I press F12 to continue it’ll do the same for Walls and Ground.

I’m a bit puzzled here. As far as I understood from the getting started tutorials in the Godot docs you can get the path to a child node using $node_name. Also, the script was working correctly, without errors, before accidentally removing it and then attaching it again by loading it.

I have the same thing with another script, attached to the player. All of a sudden the connected signals throw errors now. And whenever I run the project I get weird glitches, as if it can’t keep up with the 30 or so sprites on screen (but I think I read somewhere this has something to do with TileMap and Nvidia drivers)

Is there something I need to do after loading a script after accidentally clearing it?

On the surface, there’s no “trick” to re-attaching a script to a node. A screenshot of your scene tree might be helpful here.

jgodfrey | 2020-03-04 14:28

Edit: can’t get the image sharing to work, so link instead. Sorry! I’m going to hunt for the FAQ now

running with debugger
SceneTree with Script

fricod | 2020-03-04 23:19

:bust_in_silhouette: Reply From: jgodfrey

You could look in the scene file itself to see if your script is connected to the scene. For example, I have a Main scene in a local Godot project. That scene has a script called Main.gd attached to it.

If I look in the scene file itself (Main.tscn- just in a text editor), I see a reference to the Main.gd script as follows:

[ext_resource path="res://Scripts/Main.gd" type="Script" id=1]

Do you see a reference in your scene file to your script?

If so, is the path correct?

Also, just to make sure you’re (re)attaching the script correctly…

  • Open the scene in question
  • Select the node you want to attach the script to
  • In the Inspector, go to the bottom and open the Script dropdown
  • Choose Load
  • Select the script that should be attached to the node.

That should be it.

jgodfrey | 2020-03-04 23:59

Thanks, nice look under the hood too! I did do those steps, that’s why the code appears correctly in the script editor, I assume.

I opened Level1.tscn in a texteditor, and to my noob eyes it looks fine. The script seems to have gotten external resource id 3. Only thing that looks weird to me is why the HUD scene got id 6 instead of 4:

[gd_scene load_steps=5 format=2]

[ext_resource path=“res://tiles/TileSheet.tres” type=“TileSet” id=1]
[ext_resource path=“res://characters/Player/Player.tscn” type=“PackedScene” id=2]
[ext_resource path=“res://levels/Level1.gd” type=“Script” id=3]
[ext_resource path=“res://levels/HUD.tscn” type=“PackedScene” id=6]

[node name=“Level1” type=“Node2D”]
script = ExtResource( 3 )

[node name=“Ground” type=“TileMap” parent=“.”]
tile_set = ExtResource( 1 )
format = 1
omitting the tile_data
meta = {
edit_lock”: true
}

[node name=“Walls” type=“TileMap” parent=“.”]
tile_set = ExtResource( 1 )
format = 1
omitting the tile_data
meta = {
edit_lock”: true
}

[node name=“Items” type=“TileMap” parent=“.”]
tile_set = ExtResource( 1 )
format = 1
omitting the tile_data
meta = {
edit_lock”: true
}

[node name=“Player” parent=“.” instance=ExtResource( 2 )]
position = Vector2( 412.732, 288.513 )
script = ExtResource( 3 )

[node name=“HUD” parent=“.” instance=ExtResource( 6 )]

fricod | 2020-03-05 23:09

Hmmm… Yeah, not really sure what’s happening. Is the project available anywhere to be looked at?

jgodfrey | 2020-03-06 00:28

Sure, thanks! Dropbox link

fricod | 2020-03-06 08:19

Just took a quick look at your project. While you’re right, you have the Level1.gd script correctly attached to the Level1 scene, it’s also attached to the Player instance in the Level1 scene. I think that’s probably unintentional, and likely where you’re error is coming from…

jgodfrey | 2020-03-06 15:24

Thanks, that’s it! I do vaguely remember clicking at random in a panick after having removed the script of several scenes. Now it makes sense since the player indeed doesn’t have those nodes as children …

fricod | 2020-03-06 17:18