Confused about EditorGUILayout.Foldout use

Hi, I am creating a custom editor for a script and have managed to code out the layout alright, but I would really like three collapsible sections to it to capitalise on screen real estate. However, whilst the documentation for EditorGUILayout.Foldout gives me the impression that this is the kind I need, the example code is confusing (and I believe, in js rather than c#) and doesn’t really help.

Could a more experienced unity coder help me by illustrating in practice how I might add a Foldout to a section of this code?

using UnityEngine;
using UnityEditor;
using System.Collections;

[CustomEditor (typeof(HexDetails))]

public class HexDetailsInspector : Editor 
{
	private SerializedObject m_Object;
	private SerializedProperty m_HexPlains;
	private SerializedProperty m_HexHills;
	private SerializedProperty m_HexForest;
	private SerializedProperty m_HexMountain;
	private SerializedProperty m_HexDesert;
	private SerializedProperty m_HexMarsh;

	private SerializedProperty m_RiverHex;
	private SerializedProperty m_ResourceHex;
	private SerializedProperty m_PlantHex;
	private SerializedProperty m_DeadBodyHex;
	private SerializedProperty m_LandmarkHex;
	private SerializedProperty m_RuinHex;
	private SerializedProperty m_MonsterHex;
	private SerializedProperty m_LairHex;
	private SerializedProperty m_HutHex;
	private SerializedProperty m_TrapHex;
	private SerializedProperty m_CampHex;
	private SerializedProperty m_StructureHex;
	private SerializedProperty m_StructureType;
	private SerializedProperty m_SettlementHex;
	private SerializedProperty m_SettlementName;

	private SerializedProperty m_AqueductHex;
	private SerializedProperty m_BridgeHex;
	private SerializedProperty m_CanalHex;
	private SerializedProperty m_FarmHex;
	private SerializedProperty m_FisheryHex;
	private SerializedProperty m_FortHex;
	private SerializedProperty m_HighwayHex;
	private SerializedProperty m_MineHex;
	private SerializedProperty m_QuarryHex;
	private SerializedProperty m_RoadHex;
	private SerializedProperty m_SawmillHex;
	private SerializedProperty m_Watchtower;

	public void OnEnable()
	{
		m_Object = new SerializedObject (target);
		m_HexPlains = m_Object.FindProperty ("PlainsHex");
		m_HexForest = m_Object.FindProperty ("ForestHex");
		m_HexHills = m_Object.FindProperty ("HillsHex");
		m_HexMountain = m_Object.FindProperty ("MountainHex");
		m_HexDesert = m_Object.FindProperty ("DesertHex");
		m_HexMarsh = m_Object.FindProperty ("MarshHex");
		m_RiverHex = m_Object.FindProperty ("RiverHex");
		m_ResourceHex = m_Object.FindProperty ("ResourceHex");
		m_PlantHex = m_Object.FindProperty ("PlantHex");
		m_DeadBodyHex = m_Object.FindProperty ("DeadBodyHex");
		m_LandmarkHex = m_Object.FindProperty ("LandmarkHex");
		m_RuinHex = m_Object.FindProperty ("RuinHex");
		m_MonsterHex = m_Object.FindProperty ("MonsterHex");
		m_LairHex = m_Object.FindProperty ("LairHex");
		m_HutHex = m_Object.FindProperty ("HutHex");
		m_TrapHex = m_Object.FindProperty ("TrapHex");
		m_CampHex = m_Object.FindProperty ("CampHex");
		m_StructureHex = m_Object.FindProperty ("StructureHex");
		m_StructureType = m_Object.FindProperty ("StructureType");
		m_SettlementHex = m_Object.FindProperty ("SettlementHex");
		m_SettlementName = m_Object.FindProperty ("SettlementName");
		m_AqueductHex = m_Object.FindProperty ("AqueductHex");
		m_BridgeHex = m_Object.FindProperty ("BridgeHex");
		m_CanalHex = m_Object.FindProperty ("CanalHex");
		m_FarmHex = m_Object.FindProperty ("FarmHex");
		m_FisheryHex = m_Object.FindProperty ("FisheryHex");
		m_FortHex = m_Object.FindProperty ("FortHex");
		m_HighwayHex = m_Object.FindProperty ("HighwayHex");
		m_MineHex = m_Object.FindProperty ("MineHex");
		m_QuarryHex = m_Object.FindProperty ("QuarryHex");
		m_RoadHex = m_Object.FindProperty ("RoadHex");
		m_SawmillHex = m_Object.FindProperty ("SawmillHex");
		m_Watchtower = m_Object.FindProperty ("Watchtower");
	}

	public override void OnInspectorGUI()
	{
		//DrawDefaultInspector;
		//base.OnInspectorGUI ();
		m_Object.Update ();
		GUILayout.Label ("Hex Types", EditorStyles.boldLabel);
		EditorGUILayout.PropertyField (m_HexPlains);
		EditorGUILayout.PropertyField (m_HexForest);
		EditorGUILayout.PropertyField (m_HexHills);
		EditorGUILayout.PropertyField (m_HexMountain);
		EditorGUILayout.PropertyField (m_HexDesert);
		EditorGUILayout.PropertyField (m_HexMarsh);

		GUILayout.Label ("Terrain Features", EditorStyles.boldLabel);
		EditorGUILayout.PropertyField (m_RiverHex);
		EditorGUILayout.PropertyField (m_ResourceHex);
		EditorGUILayout.PropertyField (m_PlantHex);
		EditorGUILayout.PropertyField (m_DeadBodyHex);
		EditorGUILayout.PropertyField (m_LandmarkHex);
		EditorGUILayout.PropertyField (m_RuinHex);
		EditorGUILayout.PropertyField (m_MonsterHex);
		EditorGUILayout.PropertyField (m_LairHex);
		EditorGUILayout.PropertyField (m_HutHex);
		EditorGUILayout.PropertyField (m_TrapHex);
		EditorGUILayout.PropertyField (m_CampHex);
		EditorGUILayout.PropertyField (m_StructureHex);
		EditorGUILayout.PropertyField (m_StructureType);
		EditorGUILayout.PropertyField (m_SettlementHex);
		EditorGUILayout.PropertyField (m_SettlementName);

		GUILayout.Label ("Hex Improvements", EditorStyles.boldLabel);

		EditorGUILayout.PropertyField (m_AqueductHex);
		EditorGUILayout.PropertyField (m_BridgeHex);
		EditorGUILayout.PropertyField (m_CanalHex);
		EditorGUILayout.PropertyField (m_FarmHex);
		EditorGUILayout.PropertyField (m_FisheryHex);
		EditorGUILayout.PropertyField (m_FortHex);
		EditorGUILayout.PropertyField (m_HighwayHex);
		EditorGUILayout.PropertyField (m_MineHex);
		EditorGUILayout.PropertyField (m_QuarryHex);
		EditorGUILayout.PropertyField (m_RoadHex);
		EditorGUILayout.PropertyField (m_SawmillHex);
		EditorGUILayout.PropertyField (m_Watchtower);

		m_Object.ApplyModifiedProperties ();

		//if(GUILayout.Button ("Reset"))
		//{
		//}
	}
}

You would probably use a foldout instead of your GUILayout.Labels. Like that

protected static bool showGeneralSettings = true; //declare outside of function

protected override void OnInspectorGUI () {
    ...
    showGeneralSettings = EditorGUILayout.Foldout(showGeneralSettings, "General Settings");
    ...
}

Additionally you can format those foldouts (I’ve got the formatting code from somewhere else, don’t remember from where):

GUIStyle myFoldoutStyle = new GUIStyle(EditorStyles.foldout);
myFoldoutStyle.fontStyle = FontStyle.Bold;
myFoldoutStyle.fontSize = 14;
Color myStyleColor = Color.red;
myFoldoutStyle.normal.textColor = myStyleColor;
myFoldoutStyle.onNormal.textColor = myStyleColor;
myFoldoutStyle.hover.textColor = myStyleColor;
myFoldoutStyle.onHover.textColor = myStyleColor;
myFoldoutStyle.focused.textColor = myStyleColor;
myFoldoutStyle.onFocused.textColor = myStyleColor;
myFoldoutStyle.active.textColor = myStyleColor;
myFoldoutStyle.onActive.textColor = myStyleColor;

showGeneralSettings = EditorGUILayout.Foldout(showGeneralSettings, "General Settings",myFoldoutStyle);

So the aim is to give your custom inspector more overview. Using your example (which you already structured using GUILayout.Labels), you would insert a condition, on whether the user wants to see all details of a certain “headline” or not, like that:

protected static bool showHexTypes = true;

protected override void OnInspectorGUI () {
    showHexTypes = EditorGUILayout.Foldout(showHexTypes, "HexTypes",myFoldoutStyle);

    if (showHexTypes) {
        EditorGUILayout.PropertyField (m_HexPlains);
        EditorGUILayout.PropertyField (m_HexForest);
        EditorGUILayout.PropertyField (m_HexHills);
        EditorGUILayout.PropertyField (m_HexMountain);
        EditorGUILayout.PropertyField (m_HexDesert);
        EditorGUILayout.PropertyField (m_HexMarsh);
    }
}

So a foldout is only a “global” (class) boolean representing the current state, it makes categories of properties folding in and out. Make the boolean static to remember the state it is in during the whole Unity session (until you close Unity)