提问人:Sarah Coulston 提问时间:11/16/2023 更新时间:11/16/2023 访问量:16
需要帮助获取信号以处理库存,以便我可以与物品栏进行交互
Need help getting signals to work with inventory so I can interact with item slots
问:
我需要帮助弄清楚如何获取信号以与我的库存系统配合使用,以便我可以单击库存窗口中的物品并与之交互。我已经把它放在了正确显示我的测试玩家的库存项目的位置,但是,我试图遵循 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)
如果有人需要屏幕截图或我的节点树或任何东西,请告诉我。谢谢!
答: 暂无答案
评论