CustomPropertyDrawer for System.Guid doesn't show up

I am trying to create a property drawer for System.Guid, which does have the [Serializable] attribute.

However, public or SerializeField fields still do not show up for fields of type System.Guid.

This is my code for the property drawer:

[CustomPropertyDrawer(typeof(Guid))]
public class GuidDrawer : PropertyDrawer
{
    private VisualElement root;
    private VisualTreeAsset template;

    public override VisualElement CreatePropertyGUI(SerializedProperty property)
    {
        root = new VisualElement();
        template = ElementAssets.Template.LoadAsset();
        template.CloneTree(root);
        Debug.Log("CustomPropertyDrawer Enabled!");
        return root;
    }
}

Yet, when I select an object who has a component who has a [SerializeField] Guid field, it just doesn’t show up. No errors or other messages in the console either.

The docs only state that the type for custom property drawers must have the [Serializable] attribute, which System.Guid does. Is there something else I’m missing?

The Guid struct is not a serializable struct, so it’s not supported by Unity’s serializer. Note that Propertydrawers and CustomEditors can not change what is serialized. They can just change how the serialized data is visualized.

What you can do is create your own wrapper struct where you store the Guid as string in a serialized variable. You can implement the ISerializationCallbackReceiver for that struct to automatically translate between System.Guid and the string representation which is actually stored. Another way is to provide a property which does the translation on demand. The serialization callback solution is usually better if you need to access the GUID often. Note that the Guid struct (at least the Mono implementation) stores the GUID as one integer, two short and 8 byte values (16 bytes in total). So you don’t have to store it as string, but it’s usually the easiest format to display / edit a GUID. As you can see the Guid struct is not marked as Serializable and therefore Unity can not serialize it natively.

[Serializable]
public class SerializableGuid : ISerializationCallbackReceiver
{
    [SerializeField]
    private string m_Guid;
    public System.Guid guid;
    
    public void OnBeforeSerialize()
    {
        m_Guid = guid.ToString()
    }
    
    public void OnAfterDeserialize()
    {
        guid = System.Guid.Parse( m_Guid );
    }   
}

Note that this class does not generate a new GUID. It only allows the serialization of a GUID inside the editor or when using the JsonUtility.

To “set” a new GUID you just need to assign it to the “guid” field. When the class gets serialized OnBeforeSerialize will be called by the serializer which will convert the guid into a string. Now only the string will be serialized. If the class id deserialized OnAfterDeserialize will be called to recreate the Guid from the serialized string. You don’t need any PropertyDrawer for this solution if you just want to serialize the Guid.

The Mono Guid struct is not marked as Serializable. Even if the .NET / .NET core version has the attribute, Unity’s serializer will only serialize public fields or fields marked with Unity’s SerializeField attribute. So there would be no data serialized for the Guid struct since the data is stored in private fields.