Jrp0h Jrp0h - 18 days ago 4
C# Question

Custom Inspector Array/List not Staying in play mode

First of all i want to say Sorry for my bad english and bad grammar

i have a problem and that is when i press play in the editor my array i made in my custom editor disapares(also does that when i update the script)!

First i got a script called “ColorChangerSingle” which is the script i declare varibles

using UnityEngine;
public class ColorChangerSingle
{
public GameObject gameObjectToChange;
public Color color;
}


then i have a script called “ColorChanger” which is the script i make a custom inspector for and all it got is a static list of “ColorChangerSingle”

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ColorChanger : MonoBehaviour {
public static List<ColorChangerSingle> single = new List();
}


and i have the custom inspector script called “CustomChangeColorInspector” which is the custom inspector script.

using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(ColorChanger))]
public class CustomColorChangerInspector : Editor
{
public override void OnInspectorGUI()
{
for (int i = 0; i < ColorChanger.single.Count; i++)
{
EditorGUILayout.BeginHorizontal();
ColorChanger.single[i].gameObjectToChange = (GameObject)EditorGUILayout.ObjectField(ColorChanger.single[i].gameObjectToChange, typeof(GameObject));
ColorChanger.single[i].color = EditorGUILayout.ColorField(ColorChanger.single[i].color);
EditorGUILayout.EndHorizontal();
if (ColorChanger.single[i].gameObjectToChange != null)
if (ColorChanger.single[i].gameObjectToChange.GetComponent() != null)
ColorChanger.single[i].gameObjectToChange.GetComponent().material.color = ColorChanger.single[i].color;
}
EditorGUILayout.BeginHorizontal("box");
if (GUILayout.Button("Add To Array"))
{
ColorChanger.single.Add(new ColorChangerSingle());
}
if (GUILayout.Button("Remove Object In Array"))
{
ColorChanger.single.RemoveAt(ColorChanger.single.Count - 1);
}
EditorGUILayout.EndHorizontal();
}
}


when i add arrays in “not play mode” everything works(setting objects / changing the color of them) but when i press play the array gets “reset”, i think it has to do with the “ColorChanger” script where i set the list equal to a new list of ColorChangerSingle :/
any help is greatly appreciated!

Pictures:

https://gyazo.com/167ab826b6d578ec5a66d9d2586479e8

https://gyazo.com/847a063f9885478200c5a504be1dae2a

thanks for your time and have a great day! //Jrp0h

btw i hope the catagory is good and i know i can clean up the code alot but i made this really quick becuse im working on a secret project and did not want to use that code :)

Answer

I don't think your problem comes from the public static List<ColorChangerSingle> single = new List(); line.

What I'd recommend is adding [SerializeField] attributes to your single field and [System.Serializable] to your ColorChangerSingle class. Also are you sure your scene is saved before entering Play mode (this is a common mistake I used to do earlier on) ? If not you can add something like this at the end of the OnInspectorGUI() method :

if(GUI.changed && !Application.isPlaying)
{
    EditorUtility.SetDirty(m_Target);
    EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
}

EDIT : Also you have to give your custom inspector script a reference to the instance of the script you want to edit (think of many of your GameObjects holding a ColorChanger script), when you call ColorChanger.single[i].gameObjectToChange = [...]; your CustomColorChangerInspector inspector script doesn't know which of your GameObject you refer too.

This is why you have to reference it. The way I usually do it for quick custom inspetocrs (there is more than one way to do it, using serialization for example) is :

[CustomEditor(typeof(ColorChanger))]
public class CustomColorChangerInspector : Editor
{
    // I like to declare it once for all but you can also call "(ColorChanger)target" each time to refer to the target
    private ColorChanger m_Target;

    public override void OnInspectorGUI()
    {
        m_Target = target as ColorChanger;
        for (int i = 0; i < ColorChanger.single.Count; i++)
        {
            EditorGUILayout.BeginHorizontal();
            m_Target.single[i].gameObjectToChange = (GameObject)EditorGUILayout.ObjectField(m_Target.single[i].gameObjectToChange, typeof(GameObject));
            [...]
        }
    }
}
Comments