unity-game-engine

Unity custom editor with arrays


I'm in the process of creating a game and the scripts are getting pretty big. For more clarity I want to work with the custom editor. But I have problems with types like classes, gameobjects and especially arrays.

It is very easy to make basic types like string and float etc visible. But how does it work with an array? and especially if the array is still a class or a rigidbody or a gameobject? I need if possible a good explanation or direct solution.

enter image description here


Solution

  • Note: If you're just looking to beautify/improve your inspector, rather than doing it as an actual project/experience, your better off looking for plugins.

    The Custom-Editor API that Unity provides are a bunch of Tools, not a House.
    You will end up pouring a lot of effort into making your inspector 'look neater'.

    If you just want to create a game, use plugins to decorate your inspector.
    MyBox is one of the Plugins I use, and recommend.

    Now back to the question

    I managed to pull it off by using a combination of EditorGUILayout.Foldout and looping through the array size to create multiple EditorGUILayout.IntField.

        // True if the user 'opened' up the array on inspector.
        private bool countIntsOpened;
    
        public override void OnInspectorGUI() {
            var myTarget = (N_USE)target;
    
            myTarget.myTest.name = EditorGUILayout.TextField("see name", myTarget.myTest.name);
            myTarget.myTest.countOnly = EditorGUILayout.FloatField("see float", myTarget.myTest.countOnly);
    
            // Create int array field
            myTarget.myTest.countInts = IntArrayField("see int[]", ref countIntsOpened, myTarget.myTest.countInts);
        }
    
        public int[] IntArrayField(string label, ref bool open, int[] array) {
            // Create a foldout
            open = EditorGUILayout.Foldout(open, label);
            int newSize = array.Length;
    
            // Show values if foldout was opened.
            if (open) {
                // Int-field to set array size
                newSize = EditorGUILayout.IntField("Size", newSize);
                newSize = newSize < 0 ? 0 : newSize;
    
                // Creates a spacing between the input for array-size, and the array values.
                EditorGUILayout.Space();
    
                // Resize if user input a new array length
                if (newSize != array.Length) {
                    array = ResizeArray(array, newSize);
                }
    
                // Make multiple int-fields based on the length given
                for (var i = 0; i < newSize; ++i) {
                    array[i] = EditorGUILayout.IntField($"Value-{i}", array[i]);
                }
            }
            return array;
        }
    
        private static T[] ResizeArray<T>(T[] array, int size) {
            T[] newArray = new T[size];
    
            for (var i = 0; i < size; i++) {
                if (i < array.Length) {
                    newArray[i] = array[i];
                }
            }
    
            return newArray;
        }
    

    End Result Image

    Not as nice or neat as Unity's default. But gets the job done.