The question is answered, right answer was accepted
Custom Inspector Array Elements not saving
So, I'm trying to create a Custom Inspector for an array of custom classes, and I would like to have the ability to change the class of the array element based on a dropdown list. In my case, I have an array of the base class (Command), and I would like to be able to change the element to either a TestCommand instance or a TestLongCommand instance (both of which inherit from Command). The problem now is that when I change the elements, THE VALUE IS NEVER SAVED. Even after I set them to dirty, and set them serializable. So even if I create a list which has a 3 TestCommands and 2 TestLongCommands, they all become 5 Commands when I reload the scene/press play. Could somebody please help me out? I've been searchin for like 4 hours and haven't been able to find the solution to my problem...
CommandList.cs
[System.Serializable]
public class Command {
public virtual string commandName{
get { return this.GetType().Name;}
}
...
}
[System.Serializable]
public class CommandList : MonoBehaviour {
public List<Command> commands;
public int currCommandIndex = 0;
...
}
CommandListEditor.cs
[CustomEditor(typeof(CommandList))]
public class CommandListEditor : Editor {
CommandList script;
void OnEnable()
{
script = (CommandList)target;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PrefixLabel("Commands");
SerializedProperty commandsProp = serializedObject.FindProperty("commands");
List<string> allTypeStrings = new List<string>();
System.Type[] allTypes = Methods.GetSubclasses<Command>();
foreach(System.Type type in allTypes)
{
allTypeStrings.Add(type.Name);
}
int i = 0;
foreach(SerializedProperty childProp in commandsProp)
{
EditorGUILayout.LabelField("[" + i.ToString() + "]");
//Debug.Log(currValue);
int currIndex = -1;
if (script.commands[i] != null)
{
for (int j = 0; j < allTypeStrings.Count; ++j)
{
if (allTypeStrings[j] == script.commands[i].commandName)
currIndex = j;
}
EditorGUILayout.LabelField(script.commands[i].commandName);
}
int newIndex = EditorGUILayout.Popup(currIndex, allTypeStrings.ToArray());
if (newIndex != currIndex)
{
Debug.Log("Changed from " + ((script.commands[i] != null)?script.commands[i].commandName:"NULL") + " to " + allTypeStrings[newIndex] + " in " + serializedObject.targetObject.name);
System.Activator.CreateInstance(allTypes[newIndex]) as Command);
script.commands[i] = System.Activator.CreateInstance(allTypes[newIndex]) as Command;
}
childProp.serializedObject.ApplyModifiedProperties();
commandsProp.serializedObject.ApplyModifiedProperties();
++i;
}
if (GUI.changed)
{
EditorUtility.SetDirty(script);
EditorUtility.SetDirty(script.gameObject);
Undo.RecordObject(script, "Changed command");
EditorSceneManager.MarkSceneDirty(script.gameObject.scene);
Debug.Log("CHANGED!");
}
serializedObject.ApplyModifiedProperties();
}
}
Answer by GamezAtWork · Mar 11, 2017 at 02:27 PM
http://answers.unity3d.com/questions/14877/can-a-custom-inspector-serialize-a-list-of-derived.html
facepalm
Changing it to ScriptableObject and segregating it into different files solved it.
The funny thing was that I DID try it a while back but it didn't work, and I have no idea why.
c# property dont show and not save elements values in unity. https://answers.unity.com/questions/609468/how-to-c-public-variable-not-show-up-in-the-inspec.html