[SOLVED] Editor: How to serialize a FixedString and display it in the inspector?

Hi everyone, I’m currently working on custom editor tool using the experimental GraphView to create nodes on a graph and saving/loading them from a ScriptableObject.

Each node has a GUID, which was previously a simple string, but I’d like to convert it to a FixedString64Bytes for performances reasons. However, the inspector displays its raw byte array, whereas I’d want to display its string interpretation instead.

I’ve tried using a custom Property Drawer, but I can’t manage to retrieve the field from the serializedProperty. I precise that I’m not really well versed into editor extensions and custom inspectors, so my knowledge on the subject is very lacking.

Here is my attempt so far:

using Unity.Collections;
using UnityEditor;
using UnityEngine;

/// <summary>
/// PropertyDrawer for a FixedString
/// TODO : Make one for each FixedString type
/// </summary>
[CustomPropertyDrawer(typeof(FixedString64Bytes))]
public class FixedStringPropertyDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        // Draw fields - passs GUIContent.none to each so they are drawn without labels
        EditorGUI.BeginChangeCheck();

        string guidString = EditorGUI.TextField(position, property.serializedObject.targetObject.ToString());
        Debug.Log(guidString);

        if (EditorGUI.EndChangeCheck())
        {
              // TODO : Reassign the new value to the serializedProperty
        }
        //EditorGUI.PropertyField(position, property, label, true);
    }

    /// <summary>
    /// Ensures the field will stay at the proper position
    /// </summary>
    /// <param name="property">The property</param>
    /// <param name="label">The text</param>
    /// <returns>The proper height of the field</returns>
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        //return EditorGUI.GetPropertyHeight(property, label, true);
        return EditorGUIUtility.singleLineHeight;
    }

}

For anyone stumbling on the same issue I did, the answer was pretty straightforward:

    /// <summary>
    /// PropertyDrawer for a FixedString32Bytes
    /// </summary>
    [CustomPropertyDrawer(typeof(FixedString32Bytes))]
    public class FixedString32BytesPropertyDrawer : PropertyDrawer
    {
        #region Public methods

        /// <summary>
        /// Called when the UI is drawn
        /// </summary>
        /// <param name="position">The position of the field</param>
        /// <param name="property">The property to serialize</param>
        /// <param name="label">The text</param>
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginChangeCheck();
            string fixedStringValue = EditorGUI.TextField(position, label, property.boxedValue.ToString());

            if (EditorGUI.EndChangeCheck())
            {
                property.boxedValue = new FixedString32Bytes(fixedStringValue);
            }
        }

        /// <summary>
        /// Ensures the field will stay at the proper position
        /// </summary>
        /// <param name="property">The property</param>
        /// <param name="label">The text</param>
        /// <returns>The proper height of the field</returns>
        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            return EditorGUIUtility.singleLineHeight;
        }

        #endregion
    }

I had a couple of issues understanding SerializedProperty.boxedValue worked, but the end result is clean and concise. For the other types of FixedString, I just duplicated the class and changed the number of bytes for each of them.

1 Like