需要帮助获取信号以处理库存,以便我可以与物品栏进行交互

Need help getting signals to work with inventory so I can interact with item slots

提问人:Sarah Coulston 提问时间:11/16/2023 更新时间:11/16/2023 访问量:16

问:

我需要帮助弄清楚如何获取信号以与我的库存系统配合使用,以便我可以单击库存窗口中的物品并与之交互。我已经把它放在了正确显示我的测试玩家的库存项目的位置,但是,我试图遵循 https://www.youtube.com/watch?v=V79YabQZC1s&t=1255s 但是当我的玩家的库存(我已经检查过,即使它连接到信号时也设置正确)连接到信号。当信号被触发时,self(库存数据 self)是一个空白的库存数据集,而不是我的测试玩家的库存数据集。如果有人能帮忙。我将不胜感激!我刚刚开始学习 Godot(引擎和 GodotScript),所以我可能只是错过了一些简单的东西。但这让我发疯了。感谢您的任何帮助!

库存数据类:

extends Resource
class_name InventoryData

signal inventory_interact(inventory_data: InventoryData, index: int, button: int)

@export var slot_datas: Array[SlotData]


func remove_item(slot: SlotData) -> bool:

    return true
    
    
func add_item(slot: SlotData) -> bool:
    return true
    
func on_slot_clicked(index: int, button: int) -> void:
    inventory_interact.emit(self, index, button)
    
func grab_slot_data(index: int) -> SlotData:
    var slot_data = slot_datas[index]
    
    if slot_data:
        return slot_data
    else:
        return null

插槽节点脚本:

extends PanelContainer

signal slot_clicked(index: int, button: int)

func set_slot_data(slot_data: SlotData) -> void:
    var item_icon: TextureRect = $MarginContainer/ItemIcon
    var quantity_label: Label = $QuantityLabel
    if slot_data:       
        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()


func _on_gui_input(event: InputEvent) -> void:
    if event is InputEventMouseButton \
        and (event.button_index == MOUSE_BUTTON_LEFT \
        or event.button_index == MOUSE_BUTTON_RIGHT) \
        and event.is_pressed():
            slot_clicked.emit(get_index(), event.button_index)

插槽块(进入每个库存选项卡的库存窗口的插槽块)

extends MarginContainer


const SLOT = preload("res://inventory/slot.tscn")


func _ready() -> void:
    pass

func set_slots_block_data(inv_data: InventoryData, item_type_filter: ItemData.ITEMTYPE) -> void:
    
    var passed_inv_data: Array[SlotData] = inv_data.slot_datas

    #optional item type filter
    match int(item_type_filter):
        int(ItemData.ITEMTYPE.EQUIPPABLE):
            passed_inv_data = inv_data.slot_datas.filter(func(x): return not x or x.item_data.item_type == ItemData.ITEMTYPE.EQUIPPABLE)
            passed_inv_data.sort_custom(func(a,b): return a != null and b == null)
        int(ItemData.ITEMTYPE.FOOD):
            passed_inv_data = inv_data.slot_datas.filter(func(x): return not x or x.item_data.item_type == ItemData.ITEMTYPE.FOOD)
            passed_inv_data.sort_custom(func(a,b): return a != null and b == null)
        int(ItemData.ITEMTYPE.USABLE):
            passed_inv_data = inv_data.slot_datas.filter(func(x): return not x or x.item_data.item_type == ItemData.ITEMTYPE.USABLE)
            passed_inv_data.sort_custom(func(a,b): return a != null and b == null)
        int(ItemData.ITEMTYPE.QUEST):
            passed_inv_data = inv_data.slot_datas.filter(func(x): return not x or x.item_data.item_type == ItemData.ITEMTYPE.QUEST)
            passed_inv_data.sort_custom(func(a,b): return a != null and b == null)
        int(ItemData.ITEMTYPE.MISC):
            passed_inv_data = inv_data.slot_datas.filter(func(x): return not x or x.item_data.item_type == ItemData.ITEMTYPE.MISC)
            passed_inv_data.sort_custom(func(a,b): return a != null and b == null)

    #put in empty slots for the ones filtered out so the array is the same size as the one passed in
    var diff: int = inv_data.slot_datas.size() - passed_inv_data.size()
    var empt: Array[SlotData]
    empt.resize(diff)
    
    passed_inv_data.append_array(empt)
    
    inv_data.slot_datas = passed_inv_data
            
    populate_item_grid(inv_data)


func populate_item_grid(inventory_data: InventoryData) -> 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 inventory_data.slot_datas:
            var slot = SLOT.instantiate()       
            item_grid.add_child(slot)
            
            slot.slot_clicked.connect(inventory_data.on_slot_clicked)
            
            if slot_data:   
                slot.set_slot_data(slot_data)

                    


func _on_inventory_window_close_requested() -> void:
    pass # Replace with function body.

库存子屏幕(库存屏幕的实际库存部分 - 我为设备系统保存的实际库存屏幕的一部分。

extends PanelContainer

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

@onready var tabs: TabContainer = $HBoxContainer/MarginContainer/VBoxContainer/InventoryTabContainer


# Called when the node enters the scene tree for the first time.
func _ready() -> void:      
    pass
    


func set_inventory_panel(inv: InventoryData) -> void:
    #this was the only way I could find to get the tab names to work right. Stupid tab containersr
        
    if inv:
        var invall: Control = $HBoxContainer/MarginContainer/VBoxContainer/InventoryTabContainer/All
        var childrenall = invall.get_children()
        for c in childrenall:
            self.remove_child(c)
            c.queue_free()
        var inv_panel_all = SLOTS_BLOCK.instantiate()
        inv_panel_all.set_slots_block_data(inv, ItemData.ITEMTYPE.NULL)
        invall.add_child(inv_panel_all) 
        
        var inveq: Control = $HBoxContainer/MarginContainer/VBoxContainer/InventoryTabContainer/Equippable
        var childreneq = inveq.get_children()
        for c in childreneq:
            self.remove_child(c)
            c.queue_free()
        var inv_panel_equip= SLOTS_BLOCK.instantiate()
        inv_panel_equip.set_slots_block_data(inv, ItemData.ITEMTYPE.EQUIPPABLE)
        inveq.add_child(inv_panel_equip)
        
        var invus: Control = $HBoxContainer/MarginContainer/VBoxContainer/InventoryTabContainer/Usable
        var childrenus = invus.get_children()
        for c in childrenus:
            self.remove_child(c)
            c.queue_free()
        var inv_panel_use= SLOTS_BLOCK.instantiate()
        inv_panel_use.set_slots_block_data(inv, ItemData.ITEMTYPE.USABLE)
        invus.add_child(inv_panel_use)
        
        var invq: Control = $HBoxContainer/MarginContainer/VBoxContainer/InventoryTabContainer/Quest
        var childrenq = invq.get_children()
        for c in childrenq:
            self.remove_child(c)
            c.queue_free()
        var inv_panel_q= SLOTS_BLOCK.instantiate()
        inv_panel_q.set_slots_block_data(inv, ItemData.ITEMTYPE.QUEST)
        invq.add_child(inv_panel_q)
        
        var invfood: Control = $HBoxContainer/MarginContainer/VBoxContainer/InventoryTabContainer/Food
        var childrenfood = invfood.get_children()
        for c in childrenfood:
            self.remove_child(c)
            c.queue_free()
        var inv_panel_food= SLOTS_BLOCK.instantiate()
        inv_panel_food.set_slots_block_data(inv, ItemData.ITEMTYPE.FOOD)
        invfood.add_child(inv_panel_food)

实际库存屏幕:

extends Window

const INVSUBSCREEN = preload("res://inventory/inventory_sub_screen.tscn")

var test_inv = preload("res://test_objects/test_inventory.tres")
var grabbed_slot_data: SlotData

func _ready() -> void:
    pass


func _on_close_requested() -> void:
    self.queue_free()
    
    
func set_inventory_panel(inv: InventoryData) -> void:
    var children = self.get_children()
    for c in children:
        self.remove_child(c)
        c.queue_free()
    var invp = INVSUBSCREEN.instantiate()
    inv.inventory_interact.connect(on_inventory_interact)
    invp.set_inventory_panel(inv)
    self.add_child(invp)
    
func on_inventory_interact(inventory_data: InventoryData,
 index: int, button: int) -> void:
    
    match [grabbed_slot_data, button]:
        #if no slot data grabbed yet and left mouse button is pressed
        [null, MOUSE_BUTTON_LEFT]:
            grabbed_slot_data = inventory_data.grab_slot_data(index)
    print(grabbed_slot_data)

主屏幕主脚本:

extends Control


const BEGGAR_ENCOUNTER = preload("res://image_panel_images/beggar_encounter_image2.png")
const INTRO_IMG = preload("res://image_panel_images/start_image.png")
const INVPANEL = preload("res://inventory/inventory.tscn")
const START_PLAYER = preload("res://character/characters/start_player.tres")

@onready var image: Node = $PanelContainer/MarginContainer/MainColumns/ImagePanel/MainImage
@onready var health_manager: Node = $Scripts/HealthIconManagement
@onready var current_player: Node = $Scripts/CurrentPlayer
@onready var sub_windows: Node = $SubWindows


func _ready() -> void:
    
    image.texture = INTRO_IMG
    health_manager.set_health_to_full()
    current_player.set_character(START_PLAYER)
    
    
func _on_btn_settings_pressed() -> void:
    #settings window
    pass


func _on_button_inventory_pressed() -> void:
    var inv_panel = INVPANEL.instantiate()
    var current_player_character = current_player.character
    inv_panel.set_inventory_panel(current_player.character.inv)
    sub_windows.add_child(inv_panel)    

如果有人需要屏幕截图或我的节点树或任何东西,请告诉我。谢谢!

戈多 4

评论


答: 暂无答案