@ _ready(): Node not found:

Godot Version

v4.3.stable.official [77dcf97d8]

Question

I try to make a grid using Control nodes. I created a scene for the cells, which has a PanelContainer as scene root and a TextureRect as a child. It is created with ItemCell.new() and added as a child to a GridContainer. However, the TextureRect is never created; When i “Remote” inspect the scene of the running game, only the PanelContainer exists, but not the TextureRect. Therefore, when I try to set its texture in the func setItem(), it throws an error (see screenshots - all code and error as Text below the screenshots). Why is the TextureRect not added to the tree?

The scripts shown are all with exactly 1 owner and not autoloaded.

ItemCell scene:

The cells are instantiated in a script attached to a GridContainer which is a own scene:

And the setItems func of my ItemGrid is called in my entry point:

Code:

#ItemCell.gd
class_name ItemCell
extends PanelContainer

@onready var texture_rect: TextureRect = $TextureRect
var _item: Item
signal itemClicked(item: Item)


func setItem(item: Item) -> void:
	_item = item
	if texture_rect != null:
		texture_rect.texture = _item.texture


func _on_texture_rect_gui_input(event: InputEvent) -> void:
	if _item == null:
		return
	if event is InputEventMouseButton:
		if event.button_index == 1 and event.pressed == true:
			print("emit!")
			itemClicked.emit(_item)
#ItemGrid.gd
class_name ItemGrid
extends GridContainer

var _items: Array[Item] = []
signal itemClicked(item: Item)


func setItems(items: Array[Item]) -> void:
	_items = items
	for child in get_children():
		child.queue_free()
	for item in _items:
		var newCell := ItemCell.new()
		add_child(newCell)
		newCell.setItem(item)
		newCell.itemClicked.connect(itemClicked.emit)
#WorldNew.gd
extends Node2D

@onready var camera_2d: MainCamera = %Camera2D
@onready var tiles: Tiles = %Tiles
@onready var structures: Structures = %Structures
@onready var hot_bar: ItemGrid = %HotBar

const TILE_GROUND = preload("res://model/tiles/Tile_Ground.tres")
const TILE_MOUNTAIN = preload("res://model/tiles/Tile_Mountain.tres")
const TILE_WATER = preload("res://model/tiles/Tile_Water.tres")

const STR_MINE_STONE = preload("res://model/structures/Str_Mine_Stone.tres")

const ITEM_MINE_STONE = preload("res://model/items/Item_Mine_Stone.tres")


func _ready() -> void:
	print("Generating world.")
	_generateWorld()
	hot_bar.setItems([ITEM_MINE_STONE])
	print("Generating world done.")


func _generateWorld() -> void:
	for x in range(-10, 11):
		for y in range(-10, 11):
			tiles.setTile(TILE_WATER.duplicate(true), Vector2i(x, y))
	for x in range(-1, 2):
		for y in range(-1, 2):
			tiles.setTile(TILE_GROUND.duplicate(true), Vector2i(x, y))
	tiles.setTile(TILE_MOUNTAIN.duplicate(true), Vector2i(0, 0))
	structures.setStructure(STR_MINE_STONE, Vector2i(0, 0))
	var groundRect := tiles.getGroundGridRect()
	camera_2d.updateLimits(
		groundRect.position * C.TileSize, (groundRect.position + groundRect.size) * C.TileSize
	)

#ErrorMessage
E 0:00:00:0846   ItemCell.gd:4 @ _ready(): Node not found: "TextureRect" (relative to "/root/WorldNew/UI/HotBar/@PanelContainer@904").
  <C++ Error>    Method/function failed. Returning: nullptr
  <C++ Source>   scene/main/node.cpp:1792 @ get_node()
  <Stack Trace>  ItemCell.gd:4 @ _ready()
                 ItemGrid.gd:14 @ setItems()
                 WorldNew.gd:20 @ _ready()

ItemCell.new() makes a new PanelContainer with your script, not an entire scene, so it has no children. You need to use a preload and instantiate() to create a scene instance.

3 Likes

Thank you! That was indeed my issue.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.