Tooled custom UI node issue

Hi everyone

Godot Version

4.6

Goal

Build a custom Slot node for UI system (like inventory)

Slot script

@tool
class_name Slot
extends Control


@export var background_style_box: StyleBox: set = set_background_style_box
var background_panel: Panel


func _ready():
	# Background
	background_panel = Panel.new()
	add_child(background_panel)
	background_panel.set_anchors_preset(LayoutPreset.PRESET_FULL_RECT)



func set_background_style_box(style_box: StyleBox):
	if not is_node_ready():
		return
	background_style_box = style_box
	background_panel.add_theme_stylebox_override("panel", background_style_box)

Scene Tree

Test (Control)

  • Slot

Issue

When I add a Slot to the tree, I can edit the style box and see its changes

At runtime, nothing is shown

In remote, the panel in Theme Override Style is empty. When I try to create a new panel from there:
E 0:00:08:086 add_theme_style_override: Required object “rp_style” is null.
<C++ Source> scene/gui/control.cpp:3363 @ add_theme_style_override()

Also, when I reload the project, the panel stylbox disapear

It’s so frustating, I spent half the day trying to fix this, I feel so dumb

Thank by advance :folded_hands:

Sounds like background_style_box is null. Make sure it’s properly assigned, or make sure set_background_style_box only get called when the node is completely ready.

Try this instead:

func set_background_style_box(style_box: StyleBox):
	if not is_node_ready():
		await ready
	background_style_box = style_box
	background_panel.add_theme_stylebox_override("panel", background_style_box)

Hi everyone,

Finaly, I only needed to place _ready with _init :upside_down_face:

Here is the final code

@tool
class_name Slot
extends Control

# I set a style box in the editor. Exported values are initializedd after `_init`
@export var background_style_box: StyleBox: set = set_background_style_box 
var background_panel: Panel


func _init():
	# Background
	background_panel = Panel.new()
	add_child(background_panel)
	background_panel.set_anchors_preset(LayoutPreset.PRESET_FULL_RECT)



func set_background_style_box(style_box: StyleBox):
	if not background_panel:
		return
	background_style_box = style_box
	background_panel.add_theme_stylebox_override("panel", background_style_box)