Closed ice-ko closed 2 weeks ago
I tested it in Godot_v4.3-rc1_mono_win64 and got the same result, just copying the new instance. Why does this happen?
Please upload a minimal reproduction project to make this easier to troubleshoot.
Although I imagine what's happening here is that those members aren't annotated with the [Export]
attribute. Resource.Duplicate
only copies exported properties.
@raulsntos Yes, I tested it and found that [Export] attribute is required to copy to the new instance, but is this not friendly enough? Because in many cases we assign internal values without exporting the variable, so using Duplicate to copy becomes very unfriendly!
Godot only knows about the members you export, so it can't copy internal data. It's usually not a good idea to copy everything anyway.
If your only concern is you want to hide the exported members, that should be possible by removing the PROPERTY_USAGE_EDITOR
flag. To do this you have multiple options:
Option 1: Use _ValidateProperty
This method allows you to customize members exported with the [Export]
attribute by modifying their PropertyInfo
(including their usage flags).
public override void _ValidateProperty(Godot.Collections.Dictionary property)
{
if (property["name"].AsStringName() == PropertyName.MyInternalProperty)
{
var usage = property["usage"].As<PropertyUsageFlags>();
// Remove PROPERTY_USAGE_EDITOR flag so it doesn't show in the inspector.
usage &= ~PropertyUsageFlags.Editor;
property["usage"] = (int)usage;
}
}
Option 2: Use _GetPropertyList
This method allows you to export members without using the [Export]
attribute. It's a more advanced way of exporting members and allows you to specify the usage flags.
public override Godot.Collections.Array<Godot.Collections.Dictionary> _GetPropertyList()
{
var properties = new Godot.Collections.Array<Godot.Collections.Dictionary>();
properties.Add(new Godot.Collections.Dictionary()
{
{ "name", "MyInternalProperty" },
{ "type", (int)Variant.Type.Int },
// Set the PROPERTY_USAGE_STORAGE flag, required for 'Duplicate' to copy the property.
// We don't set the PROPERTY_USAGE_EDITOR flag, so it doesn't show in the inspector.
{ "usage", (int)PropertyUsageFlags.Storage },
});
return properties;
}
Don't forget to also override _Get
and _Set
. See their documentation for more information.
Option 3: Don't use Duplicate
Alternatively, you can always create your own method to duplicate your class instead of using the built-in Duplicate
method if it doesn't fit your needs.
public MyResource CustomDuplicate()
{
// Here we create a new instance of MyResource and set all the properties as needed.
var copy = new MyResource()
{
MyPublicProperty = this.MyPublicProperty,
MyInternalProperty = this.MyInternalProperty,
};
return copy;
}
@raulsntos Thank you. It solved my doubts and I know how to use it.
Closing as resolved.
Tested versions
Godot_v4.3-beta3_mono
System information
Godot v4.3.beta3.mono - Windows 10.0.22631 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3060 Laptop GPU (NVIDIA; 32.0.15.5599) - 12th Gen Intel(R) Core(TM) i7-12700H (20 Threads)
Issue description
Steps to reproduce
Use the Duplicate API to copy the new entity class
Minimal reproduction project (MRP)
No