Resource based inventory: item doesnt show but does exist?

Godot Version

4.6.1.stable

Question

ok so, first of all im new to this engine and a lot of the coding so bear with me, and if i forget to add an import detail im sorry please ask for it, im very greatful for any help :D

im following a tutorial series by michael games to try making an inventory system, the code should be the same, except for some little things that i added or subtracted based on what i want it too do but as far as i understand it shouldnt be the issue.

whats happening is when you run the game and open the inventory the slots are empty even when they shouldnt be, how do i know? the save data (when i press the save button in game, just a lil json file that gets editted basically) does show the items as being in the inventory.

ive used some print statements to try and determine where the error lies and i think its either in a communication between the clear_inventory function and the set_slot_data function or its because maybe it doesnt see the slotdata resource? but then the save function also shouldnt be able to see the items?

code that i think is the relevant parts(?):

code its based on from the michael games tutorial aarpg-tutorial/GUI/pause_menu/inventory/scripts at main Β· michaelmalaska/aarpg-tutorial Β· GitHub

my code:

inventory data:

class_name inventory_data extends Resource

@export var slots : Array[ slot_data ]

func _init() β†’ void:
connect_slots()
pass

func inventory_slots() β†’ Array[ slot_data ]:
return slots

func connect_slots() β†’ void:
for s in slots:
if s:
s.changed.connect( slot_changed )

func slot_changed() β†’ void:
for s in slots:
if s:
if s.quantity < 1:
s.changed.disconnect( slot_changed )
var index = slots.find( s )
slots [ index ] = null
emit_changed()
pass

func add_item( item : Item_data, count : int = 1 ) β†’ bool:
for s in slots:
if s:
if s.item_data == item:
s.quantity += count
return true

for i in slots.size():
	if slots [ i ] == null: 
		var new = slot_data.new()
		new.item_data = item
		new.quantity = count
		slots[ i ] = new
		new.changed.connect( slot_changed )
		return true

return false

func get_save_data() β†’ Array:
var item_save : Array = 

for i in slots.size():
item_save.append( item_to_save( slots [i]))
return item_save

func item_to_save(slot : slot_data) β†’ Dictionary:
var result = { item = β€œβ€, quantity = 0}
if slot != null:
result.quantity = slot.quantity
if slot.item_data != null:
result.item = slot.item_data.resource_path
return result

func parse_save_data( save_data : Array) β†’ void:
var array_size = slots.size()
slots.clear()
slots.resize( array_size )
for i in save_data.size():
slots[ i ] = item_from_save( save_data[i] )
connect_slots()

func item_from_save( save_object : Dictionary) β†’ slot_data:
if save_object.item == β€œβ€:
return null
var new_slot : slot_data = slot_data.new()
new_slot.item_data = load(save_object.item)
new_slot.quantity = int( save_object.quantity )
return new_slot

func swap_items_by_index( i1 : int, i2 : int ) β†’ void:
var temp : slot_data = slots[ i1 ]
slots[i1] = slots[i2]
slots[i2] = temp
pass

inventory slot ui:

class_name inventory_slot_ui extends Button

const PLAYER_INVENTORY = preload(β€œres://resources/inventory/player_inventory.tres”)

var slotdata : slot_data : set = set_slot_data
var click_pos : Vector2 = Vector2.ZERO
var dragging : bool = false
var drag_texture : Control
var drag_threshold : float = 24

@onready var texture_rect: TextureRect = $TextureRect
@onready var label: Label = $Label
@onready var _description: Label = $description

func _ready() β†’ void:
texture_rect.texture = null
label.text = β€œβ€
_description.hide()
button_down.connect( on_button_down)
button_up.connect( on_button_up)

func _process( _delta: float) β†’ void:
if dragging:
drag_texture.position = get_local_mouse_position() - Vector2(48, 48)
if outside_drag_threshold() == true :
drag_texture.modulate.a = 0.5
else:
drag_texture.modulate.a = 0.0

func set_slot_data( value : slot_data ) β†’ void:
slotdata = value

if slotdata == null:
	texture_rect.texture = null
	label.text = ""
	_description.text = ""
	return
texture_rect.texture = slotdata.item_data.texture
label.text = str( slotdata.quantity )
_description.text = str( slotdata.item_data.description )
return

func _on_mouse_entered() β†’ void:
if slotdata == null:
return
_description.show()

func _on_mouse_exited() β†’ void:
_description.hide()

func on_button_down() β†’ void:
click_pos = get_global_mouse_position()
dragging = true
drag_texture = texture_rect.duplicate()
drag_texture.z_index = 10
drag_texture.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(drag_texture)

func on_button_up() β†’ void:
dragging = false
if drag_texture:
drag_texture.free()
pass

func outside_drag_threshold() β†’ bool:
if get_global_mouse_position().distance_to(click_pos) > drag_threshold :
return true
return false

inventory ui:

class_name Inventory_UI extends Control

const INVENTORY_SLOT = preload(β€œres://scenes/inventory/inventory_slot.tscn”)

var hovered_item : inventory_slot_ui

@export var data : inventory_data

func _ready() β†’ void:
clear_inventory()
data.changed.connect( on_inventory_changed )

func on_inventory_changed() β†’ void:
clear_inventory()
update_inventory()
pass

func clear_inventory() β†’ void:
for c in get_children():
c.set_slot_data( null )
pass

func update_inventory() β†’ void:
clear_inventory()
var inventory_slots : Array[ slot_data ] = data.inventory_slots()

for i in inventory_slots.size():
	var slot : inventory_slot_ui = get_child( i )
	slot.set_slot_data( inventory_slots[ i ] )
	connect_item_signals( slot )
pass

func _on_tab_menu_hidden() β†’ void:
clear_inventory()
pass

func _on_tab_menu_shown() β†’ void:
update_inventory()
pass

func connect_item_signals( item : inventory_slot_ui ) β†’ void:
if not item.button_up.is_connected( _on_item_drop ):
item.button_up.connect( _on_item_drop.bind(item) )
if not item.mouse_entered.is_connected( _on_item_mouse_entered ):
item.mouse_entered.connect( _on_item_mouse_entered.bind( item ))
if not item.mouse_exited.is_connected( _on_item_mouse_exited ):
item.mouse_exited.connect( _on_item_mouse_exited)
pass

func _on_item_drop (item: inventory_slot_ui) β†’ void:
if item == null or item == hovered_item or hovered_item == null:
return
data.swap_items_by_index( item.get_index(), hovered_item.get_index())
update_inventory()
pass

func _on_item_mouse_entered(item: inventory_slot_ui) β†’ void:
hovered_item = item
pass

func _on_item_mouse_exited() β†’ void:
hovered_item = null
pass

slot data resource:

class_name slot_data extends Resource

@export var item_data : Item_data
@export var quantity : int = 0 : set = set_quantity

func set_quantity( value : int) β†’ void:
quantity = value
if quantity <1:
emit_changed()

ok i think i ended up fixing it(?) or at least it all seems to work

what i did was change the data variable in inventory ui to link specifically to the player inventory .tres (making it a const)

if anyone happens to stumble upon this post and see an error waiting to happen in that manner of fixing, please tell me!!

anyway thanks for letting me air out my thoughts here i guess? it did kinda help to write it all down

1 Like