Custom Inspector for a list of custom class members.

I am trying to make an in-editor content creator for my strategy game. I thought it was the easiest way to do it rather then type XML or hardcode class instances; output it as XML and save. But unfortunately I ran into inability to edit list members’ appearance and limit values to an extent I need.

My goal is to prevent MaxElevation and MaxHumidity from having lower values then MinElevation and MinHumidity respectively in each member. (From there I can draw analogy to apply to more tricky parts of other content generators)

My MonoBehaviour (do not mind the methods of BiomM) :

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class BiomsListGenerator : MonoBehaviour
{
	public List<BiomM> bioms;

	public void Load ()
	{
		bioms = new List<BiomM> ();
		foreach (string key in DataHub.Bioms.Keys) {
			bioms.Add (BiomM.BiomToBiomM (key, DataHub.Bioms [key]));
		}
	}

	public void Save ()
	{
		List<BiomContainer.BiomSaveFormat> biomsSF = new List<BiomContainer.BiomSaveFormat> ();
		foreach (BiomM biom in bioms) {
			biomsSF.Add (BiomM.BiomMToBiom (biom));
		}
		BiomContainer.Save (biomsSF);
	}
}

 //All you need to know are the properties of that class.

[System.Serializable]
public class BiomM
{

	public string name;

	public string officialName;

	[Range (0f, 1000f)]
	public float minElevation;

	[Range (0f, 1000f)]
	public float maxElevation;

	[Range (0f, 1000f)]
	public float minHumidity;

	[Range (0f, 1000f)]
	public float maxHumidity;

	public bool primary;

	public GameObject modelPrefab;

	public GameObject guiPrifab;

	public BiomM (string name, string officialName, float minElevation, float minHumidity, float maxElevation, float maxHumidity, bool primary, GameObject modelPrefabName, GameObject guiPrifabName)
	{
		this.name = name;
		this.officialName = officialName;
		this.minElevation = minElevation;
		this.minHumidity = minHumidity;
		this.maxElevation = maxElevation;
		this.maxHumidity = maxHumidity;
		this.primary = primary;
		this.modelPrefab = modelPrefabName;
		this.guiPrifab = guiPrifabName;
	}
	public static BiomContainer.BiomSaveFormat BiomMToBiom (BiomM bm)
	{
		string s1 = "";
		string s2 = "";
		try {
			s1 = bm.modelPrefab.name;
		} catch {
		}
		try {
			s2 = bm.guiPrifab.name;
		} catch {
		}
		return new BiomContainer.BiomSaveFormat (bm.name, new Biom (bm.officialName, bm.minElevation / 1000, bm.minHumidity / 1000, bm.maxElevation / 1000, bm.maxHumidity / 1000, bm.primary, s1, s2));
	}

	public static BiomM BiomToBiomM (string name, Biom biom)
	{
		return new BiomM (
			name,
			biom.officialName,
			biom.minElevation * 1000,
			biom.minHumidity * 1000,
			biom.maxElevation * 1000,
			biom.maxHumidity * 1000,
			biom.primary,
			Resources.Load (BiomContainer.modelPrefabFolderPath + biom.modelPrefabName) as GameObject,
			Resources.Load (BiomContainer.guiPrefabFolderPath + biom.guiPrifabName) as GameObject
		);
	}


	public static BiomM BiomToBiomM (BiomContainer.BiomSaveFormat b)
	{
		return BiomToBiomM (b.key,b.biom);
	}
}

My Editor Script:

using UnityEngine;
using System.Collections;
using UnityEditor;

[CustomEditor (typeof(BiomsListGenerator))]
public class  BiomsListGeneratorEditor: Editor
{


	public override void OnInspectorGUI ()
	{

		BiomsListGenerator blg = (BiomsListGenerator)target;

		DrawDefaultInspector (); //what should replace this?

		if (GUILayout.Button ("Load")) {
			blg.Load ();
		}
		if (GUILayout.Button ("Save")) {
			blg.Save ();
		}
	}
}

Could you achieve this using a PropertyDrawer for the BioM type?

Here is the end result for those who are interested (new Editor Script):

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;

[CustomEditor (typeof(BiomsListGenerator))]
public class  BiomsListGeneratorEditor: Editor
{

	public Dictionary<int,bool> dictionary = new Dictionary<int, bool> ();

	public override void OnInspectorGUI ()
	{
		
		BiomsListGenerator blg = (BiomsListGenerator)target;
		serializedObject.Update ();
		SerializedProperty myIterator = serializedObject.FindProperty ("bioms");
		for (int i = 0; i < short.MaxValue; i++) {
			if (!dictionary.ContainsKey (i)) {
				dictionary  *= false;*
  •  	}*
    
  •  	if (i >= 3) {*
    

dictionary = EditorGUILayout.Foldout (dictionary , myIterator.FindPropertyRelative (“officialName”).stringValue);
* }*
_ if (dictionary && i >= 3) {
* EditorGUILayout.PropertyField (myIterator);
EditorGUILayout.BeginHorizontal ();
if (GUILayout.Button (“Copy”)) {
serializedObject.FindProperty (“bioms”).InsertArrayElementAtIndex (i - 3);
}
if (GUILayout.Button (“Delete”)) {
serializedObject.FindProperty (“bioms”).DeleteArrayElementAtIndex (i - 3);
}
EditorGUILayout.EndHorizontal ();
EditorGUILayout.Space ();
EditorGUILayout.Space ();
}
if (!myIterator.Next (i < 3)) {
break;
}
}
serializedObject.ApplyModifiedProperties ();*_

* if (GUILayout.Button (“Load”)) {*
* blg.Load ();*
* }*
* if (GUILayout.Button (“Save”)) {*
* blg.Save ();*
* }*
* }*
}

[CustomPropertyDrawer (typeof(BiomM))]
public class BiomMpd : PropertyDrawer
{

* public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)*
* {*
* float minElevation = property.FindPropertyRelative (“minElevation”).floatValue;*
* float maxElevation = property.FindPropertyRelative (“maxElevation”).floatValue;*

* float minHumidity = property.FindPropertyRelative (“minHumidity”).floatValue;*
* float maxHumidity = property.FindPropertyRelative (“maxHumidity”).floatValue;*

* property.FindPropertyRelative (“name”).stringValue = EditorGUI.TextField (position, “Unique Name”, property.FindPropertyRelative (“name”).stringValue);*
* property.FindPropertyRelative (“officialName”).stringValue = EditorGUILayout.TextField (“Displayed Name”, property.FindPropertyRelative (“officialName”).stringValue);*

* EditorGUILayout.BeginHorizontal ();*
* minElevation = EditorGUILayout.FloatField (minElevation);*
* EditorGUILayout.PrefixLabel (“Elevation”);*
* maxElevation = EditorGUILayout.FloatField (maxElevation);*
* EditorGUILayout.EndHorizontal ();*

* EditorGUILayout.MinMaxSlider (ref minElevation, ref maxElevation, 0f, 1000f);*

* EditorGUILayout.BeginHorizontal ();*
* minHumidity = EditorGUILayout.FloatField (minHumidity);*
* EditorGUILayout.PrefixLabel (“Humidity”);*
* maxHumidity = EditorGUILayout.FloatField (maxHumidity);*
* EditorGUILayout.EndHorizontal ();*
* EditorGUILayout.MinMaxSlider (ref minHumidity, ref maxHumidity, 0f, 1000f);*

* property.FindPropertyRelative (“primary”).boolValue = EditorGUILayout.ToggleLeft (" Essential at the start of the game.", property.FindPropertyRelative (“primary”).boolValue);*

* property.FindPropertyRelative (“modelPrefab”).objectReferenceValue = EditorGUILayout.ObjectField (*
* new GUIContent (“In-Game Model Prefab”, “Must be located in Assets/Resources/” + BiomContainer.modelPrefabFolderPath),*
* property.FindPropertyRelative (“modelPrefab”).objectReferenceValue, typeof(GameObject), false);*
* property.FindPropertyRelative (“guiPrifab”).objectReferenceValue = EditorGUILayout.ObjectField (*
* new GUIContent (“GUI Representation Prefab”, “Must be located in Assets/Resources/” + BiomContainer.guiPrefabFolderPath),*
* property.FindPropertyRelative (“guiPrifab”).objectReferenceValue, typeof(GameObject), false);*

* property.FindPropertyRelative (“minElevation”).floatValue = minElevation;*
* property.FindPropertyRelative (“maxElevation”).floatValue = maxElevation;*

* property.FindPropertyRelative (“minHumidity”).floatValue = minHumidity;*
* property.FindPropertyRelative (“maxHumidity”).floatValue = maxHumidity;*
* }*
}