Hi all, I'm still really new to GoDot and game dev, but not so much programming.

I've been following some tutorials on YT and I feel like I have a basic understanding of things and wanted to start connecting some dots/features on my own but now find myself blocked.

In short I have a working player inventory that opens with Tab and a working interaction system. I want to be able to open the player inventory independently when pressing Tab, but when opening a chest I'd like the chest inventory to open alongside the player inventory. So I can click/drag things into the player inventory.

I am using a Canvas Layer to hold the inventory_gui for both the player and the chest. The canvas layer also has a script that handles signals for when the player inventory is opened.

Where I'm blocked is: How can I send a signal and/or reference of the chest I am opening to the Canvas Layer to be able to open the chest_gui and inventory_gui. Bonus: is there a way for me to do this dynamically, so that the canvas layer can determine which chest is being interacted with, in case there are multiple chests in the same scene?

Ill put the relevant code below and trim out anything unnecessary! Any help or direction would be greatly appreciated ^.^
(If its any help, i followed tutorials from Maker Tech, DashNothing, and Brackeys)

Canvas_script.gd


extends CanvasLayer

@onready var inventory_gui = $InventoryGUI
@onready var chest_inventory_gui = $Chest_inventory_gui

var current_chest = null

func _ready():
	inventory_gui.close_inventory()
	
func _input(event):
	if event.is_action_pressed("toggle_inventory"):
		if inventory_gui.is_open:
			inventory_gui.close_inventory()
		else:
			inventory_gui.open_inventory()

Inventory_gui.gd



signal inventory_opened
signal inventory_closed
var is_open: bool = false

@onready var slots: Array = $NinePatchRect/GridContainer.get_children()
@onready var isg_class = preload("res://scenes/GUI/item_stack_gui.tscn")
@onready var player_inventory: Inventory = preload("res://scenes/Farming/Resources/player_inventory.tres")

		
func open_inventory():
	visible = true
	is_open = true	
	emit_signal("inventory_opened")
func close_inventory():
	visible = false
	is_open = false
	emit_signal("inventory_closed")

chest_inventory_gui.gd



var chest_is_open: bool = false
signal chest_inventory_opened
signal chest_inventory_closed

func open():
	visible = true
	chest_is_open = true
	emit_signal("chest_inventory_opened")
func close():
	visible = false
	chest_is_open = false
	emit_signal("chest_inventory_closed")

Interaction_manager.gd



@onready var player = get_tree().get_first_node_in_group("Player")
@onready var label = $Label

const base_text = "[E] to "

var active_areas = []
var can_interact = true

func register_area(area: InteractionArea):
	active_areas.push_back(area)
	
func unregister_area(area: InteractionArea):
	var index = active_areas.find(area)
	if index != -1:
		active_areas.remove_at(index)


func _process(delta):
	if active_areas.size() > 0 && can_interact:
		active_areas.sort_custom(_sort_by_distance_to_player)
		label.text = base_text + active_areas[0].action_name
		label.global_position = active_areas[0].global_position
		label.global_position.y -=36
		label.global_position.x -= label.size.x / 2
		label.show()
	else:
		label.hide()

func _sort_by_distance_to_player(area1, area2):
	var area1_to_player = player.global_position.distance_to(area1.global_position)
	var area2_to_player = player.global_position.distance_to(area2.global_position)
	return area1_to_player < area2_to_player
	
func _input(event):
	if event.is_action_pressed("interact") && can_interact:
		if active_areas.size() > 0:
			can_interact = false
			label.hide()
			
			await active_areas[0].interact.call()
			
			can_interact = true

interaction_area.gd


class_name InteractionArea

@export var action_name: String = "Interact"

var interact: Callable = func():
	pass


func _on_body_entered(body):
	if body.is_in_group("Player"):
		InteractionManager.register_area(self)


func _on_body_exited(body):
	if body.is_in_group("Player"):
		InteractionManager.unregister_area(self)

Chest trying to be opened


extends StaticBody2D

@onready var sprite_2d = $Sprite2D
@onready var interaction_area: InteractionArea = $InteractionArea
@export var chest_inventory: Inventory

var chest_is_open: bool = false
func _ready():
	interaction_area.interact = Callable(self, "_on_interact")
	
func _on_interact():
	if(!chest_is_open):
		sprite_2d.frame = 4
		chest_is_open = true
		interaction_area.action_name = " close chest."
	else:
		sprite_2d.frame = 1
		chest_is_open = false
		interaction_area.action_name = " open chest."

pls format the code using ``` tags above and from below.

Also why use await?

Conceptually, if you trigger a chest, you should know what chest it is and what items it has, so connect chest script signal to the canvas on chest entering the game.

Thanks! Ill give that a try tomorrow when I get the chance and see if i can get that to work. As I step back, I've realized I may be over-engineering this and making it more complicated than need be. Because youre right, I just need a signal to the canvas layer to open the gui for the chest, scripts elsewhere will handle whats inside and moving it around.

Also I'm not 100% sure about the await call and the need to make it async, that was from one of the tutorials I was following on creating interaction areas.

Edit. Maybe instead of calling interact on itself, I can send this signal out to the canvas layer script.

func _ready():
	interaction_area.interact = Callable(self, "_on_interact")

    JR41 ive done few rewrites on inventory system following multiple tutorials and still havent figured out a working way to do things.. so just keep fighting.. im no mechanic but i think await is used if at all for things that is going outside the godot engine, like if you send http request and need to await the data then use await to block that function, but in godot everything gets piped to the process and it gets done as resources are available? xyz can comment on this one im not so sure.