Ilya Mashin
Ilya Mashin

Reputation: 954

How to display & modify array in the Editor Window?

I have GameObject array field in my CustomEditor class derived from the UnityEngine.Editor. I need to be able to display (draw) and give user ability to modify that array.

Just like how Unity's Inspector doing this for Serializable fields of objects derived from the ScriptableObject. E.g. displaying materials array in the inspector: .

Upvotes: 5

Views: 27746

Answers (5)

Victor
Victor

Reputation: 373

Refer to yours editor object as to the SerializedObject and then find any required property, draw it, and apply modification:

public class MyEditorWindow : EditorWindow
{
    [MenuItem("Window/My Editor Window")]
    public static void ShowWindow()
    {
        GetWindow<MyEditorWindow>();
    }

    public string[] Strings = { "Larry", "Curly", "Moe" };

    void OnGUI()
    {
        // "target" can be any class derived from ScriptableObject 
        // (could be EditorWindow, MonoBehaviour, etc)
        ScriptableObject target = this;
        SerializedObject so = new SerializedObject(target);
        SerializedProperty stringsProperty = so.FindProperty("Strings");

        EditorGUILayout.PropertyField(stringsProperty, true); // True means show children
        so.ApplyModifiedProperties(); // Remember to apply modified properties
    }
}

Original answer here.

Upvotes: 11

amitklein
amitklein

Reputation: 1395

The top answer didn't work well for me because the properties did not update, there for I moved the declaration lines to the OnEnable function you do not want to declare them over and over again) and used to so.Update() to update the changed variables.

using UnityEngine;
using UnityEditor;

public class MyEditorWindow : EditorWindow
{
    [MenuItem("Window/My Editor Window")]
    public static void ShowWindow()
    {
        GetWindow<MyEditorWindow>();
    }

    public string[] Strings = { "Larry", "Curly", "Moe" };
    SerializedObject so;

    private void OnEnable()
    {
        ScriptableObject target = this;
        so = new SerializedObject(target);
    }

    void OnGUI()
    {
        // "target" can be any class derived from ScriptableObject 
        // (could be EditorWindow, MonoBehaviour, etc)
        so.Update();
        SerializedProperty stringsProperty = so.FindProperty("Strings");

        EditorGUILayout.PropertyField(stringsProperty, true); // True means show children
        so.ApplyModifiedProperties(); // Remember to apply modified properties
    }
}

Links:

Base for my answer

SerializedObject.Update

Upvotes: 1

santaclos
santaclos

Reputation: 326

I managed to do it with a for loop and an extra int:

using UnityEditor;
using UnityEngine;

public class RockSpawner : EditorWindow
{
    int rockCollectionSize = 0;
    GameObject[] rockCollection;

    [MenuItem("Tools/Rock Spawner")]
    public static void ShowWindow()
    {
        GetWindow(typeof(RockSpawner));
    }

    void OnGUI()
    {
        rockCollectionSize = EditorGUILayout.IntField("Rock collection size", rockCollectionSize);
        if (rockCollection != null && rockCollectionSize != rockCollection.Length)
            rockCollection = new GameObject[rockCollectionSize];
        for (int i = 0; i < rockCollectionSize; i++)
        {
            rockCollection[i] = EditorGUILayout.ObjectField("Rock " + i.ToString(), rockCollection[i], typeof(GameObject), false) as GameObject;
        }
    }
}

Upvotes: 1

Alexander_F
Alexander_F

Reputation: 2877

add a public array to your script

public GameObject[] myObjects

Upvotes: -2

Tom
Tom

Reputation: 2472

public GameObject[] yourGameObjects;

Then in the inspector set your size, and fields should open up.

Upvotes: -2

Related Questions