Reputation: 1
I'm hoping someone will be able to help. I'm probably just missing something obvious. I'm trying to make an inventory system in Godot, using a slot scene, a slot block scene (which has a grid of slot scenes), and an inventory screen scene (which has a tab container of slot block scenes. But I'm getting this error: Invalid set index 'texture' (on base: 'Nil') with value of type 'AtlasTexture'. in the slot scene.
Script for slot scene:
extends PanelContainer
@onready var item_icon: TextureRect = $MarginContainer/ItemIcon
@onready var quantity_label: Label = $QuantityLabel
func set_slot_data(slot_data: SlotData) -> void:
var item_data = slot_data.item_data
item_icon.texture = item_data.item_icon
tooltip_text = "%s\n%s" % [item_data.name, item_data.description]
if slot_data.quantity > 1:
quantity_label.text = "x%s" % slot_data.quantity
quantity_label.show()
Script for slot block scene:
extends MarginContainer
const SLOT = preload("res://inventory/slot.tscn")
func _ready() -> void:
pass
func set_slots_block_data(slot_datas: Array[SlotData], item_type_filter: ItemData.ITEMTYPE) -> void:
var passed_inv_data: Array[SlotData] = slot_datas
#optional item type filter
if item_type_filter and item_type_filter != ItemData.ITEMTYPE.NULL:
match item_type_filter:
ItemData.ITEMTYPE.EQUIPPABLE:
passed_inv_data = passed_inv_data.filter(func(x): return x.item_data.item_type == ItemData.ITEMTYPE.EQUIPPABLE)
ItemData.ITEMTYPE.FOOD:
passed_inv_data = passed_inv_data.filter(func(x): return x.item_data.item_type == ItemData.ITEMTYPE.FOOD)
ItemData.ITEMTYPE.USABLE:
passed_inv_data = passed_inv_data.filter(func(x): return x.item_data.item_type == ItemData.ITEMTYPE.USABLE)
ItemData.ITEMTYPE.QUEST:
passed_inv_data = passed_inv_data.filter(func(x): return x.item_data.item_type == ItemData.ITEMTYPE.QUEST)
ItemData.ITEMTYPE.MISC:
passed_inv_data = passed_inv_data.filter(func(x): return x.item_data.item_type == ItemData.ITEMTYPE.MISC)
populate_item_grid(passed_inv_data)
func populate_item_grid(slot_datas: Array[SlotData]) -> void:
var item_grid = $"ScrollContainer/MarginContainer/ItemGrid"
var children = item_grid.get_children()
if children:
for child in children:
child.queue_free()
for slot_data in slot_datas:
var slot = SLOT.instantiate()
slot.set_slot_data(slot_data)
item_grid.add_child(slot)
Script for inventory screen scene:
extends PanelContainer
@onready var inventory_tab_container: TabContainer = $HBoxContainer/MarginContainer/VBoxContainer/InventoryTabContainer
const SLOTS_BLOCK = preload("res://inventory/inventory_slots_block.tscn")
var test_inv = preload("res://test_objects/test_inventory.tres")
var slotdatas = test_inv.slot_datas
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
set_inventory_panel(slotdatas)
func set_inventory_panel(inv: Array[SlotData]) -> void:
var children = inventory_tab_container.get_children()
for c in children:
self.remove_child(c)
c.queue_free()
if inv:
var inv_panel_all = SLOTS_BLOCK.instantiate()
inv_panel_all.set_slots_block_data(inv, ItemData.ITEMTYPE.NULL)
inventory_tab_container.add_child(inv_panel_all)
ItemData class:
extends Resource
class_name ItemData
const MAX_VALUE: int = 1000000
#name of the item
@export var name: String = ""
#description for the item
@export_multiline var description: String = ""
#value in currency for a single unit of the item
@export_range(0,MAX_VALUE) var value: int = 0
#determines max hit points of item
@export var max_hp: int = 1
#determines if item is indestructable
@export var indestructable: bool = false
#item type of item
@export var item_type: ITEMTYPE = ITEMTYPE.MISC: set = set_item_type
#item icon
@export var item_icon: AtlasTexture
#determines if an item is stackable
@export var stackable: bool = false
enum ITEMTYPE {
EQUIPPABLE,
FOOD,
USABLE,
QUEST,
MISC,
NULL,
}
func set_item_type(new_value: ItemData.ITEMTYPE):
item_type = new_value
func decrease_value(change: int = 0):
var prev_value = value
value = value - change
func increase_value(change: int = 0):
var prev_value = value
value = value + change
Inventory Data class:
extends Resource
class_name InventoryData
@export var slot_datas: Array[SlotData]
Slot data class:
extends Resource
class_name SlotData
const MAX_STACK_SIZE:int = 99
@export var item_data: ItemData
@export_range(1, MAX_STACK_SIZE) var quantity: int = 1: set = set_quantity
func set_quantity(value: int) -> void:
quantity = value
if quantity > 1 and not item_data.stackable:
quantity = 1
push_error("%s is not stackable, setting quantity to 1" % item_data.name)
Any ideas on what I'm messing up? I can run the slots block scene fine, but when I try to run the inventory screen, it gives me that error.
I expect that the inventory screen scene when I load it (with my test inventory, which has 20 slot data slots, and two of them have slot data in them.
item 1 (ration) item 2 (necklace)
Seems to be erroring on the first slot (the one with rations in it)
Upvotes: 0
Views: 360
Reputation: 1
I figured it out! I needed to move the item_icon and quantity label variables to inside the set_slot_data function in the slot scene.
Upvotes: 0