Looking at the code, I do not see anything right off that would indicate why it's not working. Maybe the custom category is causing the issue?
I'm not sure if it will help, but here's a snippet of how I've used _GetPropertiesList
in C# for my IK plugin:
public override bool _Set(string property, object value)
{
// ===========================================
// ===== AUTOMATION
if (property == "settings/auto_get_twisted_skeleton") {
// Code to set the skeleton here
PropertyListChangedNotify();
return true;
}
else if (property == "settings/path_to_twisted_skeleton") {
path_to_twisted_skeleton = (NodePath)value;
return true;
}
else if (property == "settings/auto_calcualte_bone_length") {
auto_calcualte_bone_length = (bool)value;
// Code to calculate the bone length (if true) here
return true;
}
// ===========================================
// ===== BONE DATA
if (property == "bone_data/bone_name") {
bone_name = (string)value;
// Code to set the bone name, get the id, etc, here
PropertyListChangedNotify();
return true;
}
else if (property == "bone_data/bone_id") {
bone_id = (int)value;
if (bone_id <= -1) {
bone_id = -1;
PropertyListChangedNotify();
return true;
}
// Code to set the bone id, name, etc, here
PropertyListChangedNotify();
return true;
}
// more properties defined - just removed for this example
// ===========================================
// I'm not totally sure if this is needed, but I found it was sometimes needed to get normal node properties, ones from built-in nodes, working correctly in the inspector
try {
return base._Set(property, value);
} catch {
return false;
}
}
public override object _Get(string property)
{
// ===========================================
// ===== AUTOMATION
if (property == "settings/auto_get_twisted_skeleton") {
return auto_get_twisted_skeleton;
}
else if (property == "settings/path_to_twisted_skeleton") {
return path_to_twisted_skeleton;
}
else if (property == "settings/auto_calcualte_bone_length") {
return auto_calcualte_bone_length;
}
// ===========================================
// ===== BONE DATA
if (property == "bone_data/bone_name") {
return bone_name;
}
else if (property == "bone_data/bone_id") {
return bone_id;
}
// more properties defined - just removed for this example
// ===========================================
try {
return base._Get(property);
} catch {
return false;
}
}
public override Godot.Collections.Array _GetPropertyList()
{
Godot.Collections.Array list = new Godot.Collections.Array();
Godot.Collections.Dictionary tmp_dict;
// ===========================================
// ===== AUTOMATION
tmp_dict = new Godot.Collections.Dictionary();
tmp_dict.Add("name", "settings/auto_get_twisted_skeleton");
tmp_dict.Add("type", Variant.Type.Bool);
tmp_dict.Add("hint", PropertyHint.None);
tmp_dict.Add("usage", PropertyUsageFlags.Default);
list.Add(tmp_dict);
if (auto_get_twisted_skeleton == false) {
tmp_dict = new Godot.Collections.Dictionary();
tmp_dict.Add("name", "settings/path_to_twisted_skeleton");
tmp_dict.Add("type", Variant.Type.NodePath);
tmp_dict.Add("hint", PropertyHint.ResourceType);
tmp_dict.Add("hint_string", "Skeleton");
tmp_dict.Add("usage", PropertyUsageFlags.Default);
list.Add(tmp_dict);
}
tmp_dict = new Godot.Collections.Dictionary();
tmp_dict.Add("name", "settings/auto_calcualte_bone_length");
tmp_dict.Add("type", Variant.Type.Bool);
tmp_dict.Add("hint", PropertyHint.None);
tmp_dict.Add("usage", PropertyUsageFlags.Default);
list.Add(tmp_dict);
// ===========================================
// ===== BONE DATA
tmp_dict = new Godot.Collections.Dictionary();
tmp_dict.Add("name", "bone_data/bone_name");
tmp_dict.Add("type", Variant.Type.String);
tmp_dict.Add("hint", PropertyHint.None);
tmp_dict.Add("usage", PropertyUsageFlags.Default);
list.Add(tmp_dict);
tmp_dict = new Godot.Collections.Dictionary();
tmp_dict.Add("name", "bone_data/bone_id");
tmp_dict.Add("type", Variant.Type.Int);
tmp_dict.Add("hint", PropertyHint.None);
tmp_dict.Add("usage", PropertyUsageFlags.Default);
list.Add(tmp_dict);
// More properties defined below, but they use the same format
// ===========================================
return list;
}
I've removed a little of the code that is not relevant (and to fit the max character limit for posting), but that's how I've used it and it seems to save fine in the Godot editor. I'm not sure why your code is not working though, it seems pretty similar to how I've done it.