Hello, I’m working on a system where the player has a skills menu and that talking to certain NPCs will add new skills to the menu. The system’s spread across a few scenes, but I’ve used print statements to make sure the process is working. It works when I ask them to print things like “yes” but also if I get it to print out the skill name, meaning the code is working and the information about the skill is being passed on, just not put onto the skill menu screen.
Here’s the full code for the final part of the process - the skill slot scene. When a new skill is being added, I want a new skill slot to appear in the menu with updated text reflecting the skill’s name and effects. The “set_empty” function works too, setting the default skill slots to having no text.
@tool # lets things be visibly changing in the game and in the editor I think?
extends Control
# define item properties
@export var skill_signal = ""
@export var skill_name = ""
@export var skill_description = ""
@export var skill_logo: Texture
var scene_path = "res://Scenes/skill.tscn"
# Node references
@onready var icon = $innerborder/skillicon
@onready var Skill_name = $innerborder/name
@onready var Skill_description = $innerborder/description
@onready var usage_panel = $"Usage Panel"
@onready var button = $innerborder/Button
# slot skill
var skill = null
var current_skill = null
# adding the skill, skill dictionary
func add_skill():
skill = {
"skill_signal" : skill_signal,
"skill_name" : skill_name,
"skill_description" : skill_description,
"skill_logo" : skill_logo,
"scene_path" : scene_path,
}
if Global.player_node:
Global.add_skill(skill)
# shows usage
func _on_button_pressed():
# if skill != null:
usage_panel.visible = !usage_panel.visible
# create empty slots with no values
func set_empty():
icon.texture = null
Skill_description.text = ""
Skill_name.text = ""
# add new skill with stuff from dictionary
func set_skill(new_skill):
skill = new_skill
icon.texture = new_skill["skill_logo"]
Skill_name.text = str(skill["skill_name"])
Skill_description.text = str(skill["skill_description"])
print(Skill_description.text)
# if you don't use that skill
func _on_no_button_pressed():
usage_panel.visible = false
# if you do want the skill
func _on_yes_button_pressed():
current_skill = skill["skill_signal"]
It’s probably something really obvious, any input is appreciated!
No sorry, the yes button is part of the menu ui. When that’s pressed, it’s supposed to send a signal to another scene (maybe the player) so I can code what those skills do. I haven’t finished this bit yet.
The process is meant to be:
The skill’s details (name, effect etc.) are set in the NPC scene. After the conversation with that NPC finishes, it instantiates one of the skill_slot scenes and uses the “add_skill” function, calling the global “add_skill” function too.
The global “add_skill” goes through the menu checking for an empty slot and sends the “update_skills” signal to the ui, calling this function:
# update skill ui
func _on_skills_updated():
clear_grid_container()
# add slots for each inventory position
for skill in Global.SkillSet:
var slot = Global.skill_slot_scene.instantiate()
gridcontain.add_child(slot)
# check if the slot has an item, create empty or populate
if skill != null:
slot.set_skill(skill)
else:
slot.set_empty()
Which then calls “set_skill” in the original script I sent.
All of this seems to work, since the print statements work, but I want “set_skill” to replace the labels on the skill slot ui and print the skill’s skill_signal when the yes_button is pressed. For some reason this isn’t happening even though I know the skill is being successfully passed between the scenes.
Thank you, I tried that and at it looks like the set empty and set skill are working correctly, the size of the skill menu is 10, so it sets the skill in the first position and sets the other 9 to empty:
Though the size of the menu is 10, it looks like it only shows one (the last) skill in the menu, it has been setting the skill correctly, just not showing it. I changed the menu size to 1 and it showed the skill as it was supposed to:
If you use a dictionary often the entries can be jumbled when retrieved. For example dictionary.get_values() returns an array of the values sorted alphabetically. An array would return them in indexed order. Since you say bob is last but for some reason shows up first.
Could also be that they are all on top of eachother. Is gridcontain still a grid container or have you changed its type somewhere along the way?
I think it’s an array, it’s defined in the global script by
var SkillSet = []
I think the menu screen is only showing the last skill in the array. When you get given a new skill it replaces the first null value, so if I have more than one spot in the array, the new skill will never be shown on the menu. I checked by adding a second NPC who gives a skill and the second skill is put into the second space in the array, not overwriting the first.
It is still a grid container, but only has one column. Is there a way to control position/size of rows independently or is that just determined by the size of the children?
I think I’ve found the issue, I hadn’t defined the sizes of the children properly, so they weren’t sorting nicely in the grid. Thanks so much for the help!