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()