CustomEditor Serialization not working

Good day.

I’m working on a custom inspector with a drop-down list for specifying the command name and then updating the parameters array based on the chosen command name. Both of the mentioned attributes are referenced using a CSV file. The problem is, the object attribute keeps reverting every time I play the editor or even by just deselecting the object. I know there were similar instances that were asked here, but I already tried their solutions and none of them worked as of now. Here’s how I implemented the said inspector:

[System.Serializable]
public class TileTreasure : MonoBehaviour {
	[SerializeField]
	private string commandName;

	[SerializeField]
	private string[] paramList;

	// Use this for initialization
	void Start () {
		Debug.Log("Name: " + this.commandName);

		for(int i = 0; i < this.paramList.Length; i++) {
			Debug.Log("Param " + (i + 1).ToString() + ":" + this.paramList[i]);
		}
	}
	
	// Update is called once per frame
	void Update () {
	
	}

	public string CommandName {
		get {
			return this.commandName;
		}

		set {
			this.commandName = value;
		}
	}

	public string[] ParamList {
		get {
			return this.paramList;
		}
	}

	public void SetParams(ArrayList command) {
		if(command.Count == 0) {
			return;
		}

		this.paramList = new string[command.Count - 1];

		// start with 1 since 0 contains command name
		for(int i = 1; i < command.Count; i++) {
			this.paramList[i - 1] = (string)command[i];
		}
	}
}
[CustomEditor(typeof(TileTreasure))]
public class TreasureModifier : InspectorBase<TileTreasure> {
	ArrayList rowList = new ArrayList();
	int index = -1;

	public override void OnInspectorGUI() {
		int oldIndex = index;

		if(index < 0) {
			index = 0;
		}

		index = EditorGUILayout.Popup(index, ConstructTreasureList());
		ArrayList singleRow = (ArrayList)rowList[index];
		Target.CommandName = (string)singleRow[0];

		if(oldIndex != index) {
			Target.SetParams(singleRow);
		}

		serializedObject.Update();
		SerializedProperty commandParams = serializedObject.FindProperty("paramList");
		EditorGUILayout.PropertyField(commandParams, true);
		serializedObject.ApplyModifiedProperties();
		
		if(GUI.changed) {
			EditorUtility.SetDirty(Target);
		}
	}

	private string[] ConstructTreasureList() {
		CsvReader reader = new CsvReader("Assets/Editor/InputFiles/TreasureList.csv");
		CsvRow row = new CsvRow();

		while(reader.ReadRow(row)) {
			ArrayList singleRow = new ArrayList();

			foreach(string s in row) {
				singleRow.Add(s);
			}

			rowList.Add(singleRow);
		}

		string[] commandNames = new string[rowList.Count];

		for(int i = 0; i < commandNames.Length; i++) {
			ArrayList singleRow = (ArrayList)rowList[i];
			commandNames[i] = (string)singleRow[0];
		}

		return commandNames;
	}
}

My apologies for the long code snippet. I would also like to add that I already tried putting the command and parameter list in a separate Serializable class and then use it as a SerializedField in the TileTreasure class. The same thing happens.

I hope someone can help me here. Thanks in advance. :slight_smile:

I figured out the problem. It’s not with the serialization process but rather on the way the custom inspector is handled. All the values in the editor script are reset when the selected object loses its focus, so the values are reset since I always invoke the setting of values inside OnInspectorGUI. Iadded some checking of existing values and changed the order of statements. I don’t even have to use SetDirty in my modified code.

public override void OnInspectorGUI() {
		string[] treasureList = ConstructTreasureList();

		if(Target.CommandName == null) {
			index = -1;
		}
		else {
			index = FindIndex(Target.CommandName, treasureList);
		}

		int oldIndex = index;

		if(index == -1) {
			index = 0;
		}

		serializedObject.Update();
		EditorGUI.BeginChangeCheck();
		index = EditorGUILayout.Popup(index, ConstructTreasureList());
		ArrayList singleRow = (ArrayList)rowList[index];
		Target.CommandName = (string)singleRow[0];
		
		if(oldIndex != index) {
			Target.SetParams(singleRow);
		}

		EditorGUILayout.PropertyField(commandParams, true);

		if(EditorGUI.EndChangeCheck()) {
			serializedObject.ApplyModifiedProperties();
		}
}