How to dynamically add properties in the inspector in Godot 4? Overriding _get_property_list no longer works

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Sniperchang

In Godot 3.x, it was easy to add properties and property categories by overriding _get_property_list().

The following example, based on the docs, will show the test property in Godot 3.4.3 inspector when the following script is attached to a node:

tool
class_name PropTest extends Node

var test:int = 10 # We will store the value here

func _get(property):
	if property == "my_property":
		return test # One can implement custom getter logic here

func _set(property, value):
	if property == "my_property":
		test = value # One can implement custom setter logic here
		return true

func _get_property_list():
	var properties = []
	# Same as "export(int) var my_property"
	properties.append({
		name = "my_property",
		type = TYPE_INT
	})
	return properties

If I try the exact same code in Godot 4 (adding @ before tool), it doesn’t update the inspector. The _get_property_list method does get called, easily visible by adding a print call, but the property doesn’t show in the inspector.

The latest docs has changed, and removed this exmaple. Is it no longer possible to do this with GDScript?

i would also like to know the answer to this question, as my properties are no longer exporting in the most frustrating way after attempting to port

WolframR | 2022-07-04 21:21

I have the same issue. I now filed a bug, because it seems that there are some issue in Godot 4 (see here and here)

st_phan | 2023-04-05 08:43

A helpful person mentioned that you have to reload the scene in order for it to work!

st_phan | 2023-04-05 09:32

:bust_in_silhouette: Reply From: FeralBytes0

func get_property_list() still works the same as before.

var subdivision: int = 1
var subdivisions_array = []
var subdivisions_hint = ""

func _get_property_list():
    var props = []
    props.append({name="subdivision", type=TYPE_INT, hint=PROPERTY_HINT_ENUM,
        hint_string=subdivisions_hint, useage=PROPERTY_USAGE_DEFAULT}
    )
    return props

But set and get are different now, more like this:

@export var mesh_size: int = 5120:
    set(new_size):
        mesh_size = new_size
        build_subdivision_list(new_size)
        notify_property_list_changed()

See the new documentation here for set and get: GDScript reference — Godot Engine (latest) documentation in English