Search code examples
c#unity-game-engineunity-editor

Unity editor script that will make a visual object field for an array element and will let me edit it


I have a script in which I have declared an array of sprites. I want to represent it in a nice way in the editor and don't want to make it noticeable that it's an array.

This is what my script looks like:

public class SkinData : ScriptableObject
{
    public Sprite[] FaceDownSprites = new Sprite[MaxFrameCount];
}

And this is what the editor script looks like:

[CustomEditor(typeof(SkinData))]
public class SkinDataEditor : UnityEditor.Editor
{
    private const float SpriteFieldSize = 100f;

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        SkinData skinData = (SkinData)target;

        GUILayout.Label("Tilesheet");
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.ObjectField(skinData.FaceDownSprites[0], typeof(Sprite), GUILayout.Height(SpriteFieldSize), 
        GUILayout.Width(SpriteFieldSize));
        GUILayout.Width(SpriteFieldSize));
        EditorGUILayout.ObjectField(skinData.FaceDownSprites[1], typeof(Sprite), GUILayout.Height(SpriteFieldSize),
        GUILayout.Width(SpriteFieldSize));
        EditorGUILayout.ObjectField(skinData.FaceDownSprites[2], typeof(Sprite), GUILayout.Height(SpriteFieldSize),
        GUILayout.Width(SpriteFieldSize));
        EditorGUILayout.EndHorizontal();
    }
}

This is how it looks to give you an idea of what I wanted to achieve, the arrays won't be visible in the final version

The problem is it works only partially, it shows the sprites from the array in the newly created fields, but it doesn't let me edit/add sprites. Nothing happens when I drag and drop the sprite to the new field. It doesn't change in the array as well. Any idea how to make it work?


Solution

  • This method:

    EditorGUILayout.ObjectField();
    

    returns the object that you have just assigned. So if you want to keep changes, you should do this:

    skinData.FaceDownSprites[0] = (Sprite) EditorGUILayout.ObjectField(skinData.FaceDownSprites[0], typeof(Sprite), GUILayout.Height(SpriteFieldSize), GUILayout.Width(SpriteFieldSize));
    

    And also if you are doing changes on the assets, research these: https://docs.unity3d.com/ScriptReference/EditorUtility.SetDirty.html https://docs.unity3d.com/ScriptReference/AssetDatabase.SaveAssetIfDirty.html https://docs.unity3d.com/ScriptReference/AssetDatabase.SaveAssets.html