- Home /
Create Multiple Foldouts.
Hi all, I'm trying to create a multiple group of foldout options, I've gotten close but some-things are messing up. Either they all open at once, or I get out of range exceptions. Can anyone help me out?
Here is my code. Thanks in advance!
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
public class TrophyEditor : EditorWindow {
TrophyList trophyDB;
Vector2 scroll = Vector2.zero;
List<bool> collapse = new List<bool>();
[MenuItem("Tools/Trophy Editor")]
static void Initialize() {
var window = ScriptableObject.CreateInstance<TrophyEditor>();
window.title = "Trophy Editor";
window.ShowUtility();
}
void OnEnable() {
trophyDB = Resources.Load<TrophyList>("Data/TrophyList");
// If the trophy list is empty, initialize it
if (trophyDB.trophiesList.Count == 0) {
trophyDB.trophiesList.Add(new Trophy());
}
}
void OnDestroy() {
Save();
}
void Save() {
AssetDatabase.Refresh();
EditorUtility.SetDirty(trophyDB);
AssetDatabase.SaveAssets();
}
void OnGUI() {
GUILayout.BeginHorizontal(EditorStyles.toolbar);
if (GUILayout.Button("Save", EditorStyles.toolbarButton)) {
Save();
EditorUtility.DisplayDialog("Save Asset", "The list of Trophies has been saved!", "Okay");
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
EditorGUILayout.HelpBox("Welcome to the Trophy Editor.\n", MessageType.Info);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical();
scroll = EditorGUILayout.BeginScrollView(scroll);
foreach (Trophy t in trophyDB.trophiesList) {
for (int i = 0; i < collapse.Count; ++i) {
collapse[i] = EditorGUILayout.Foldout(collapse[i], "Trophy: " + t.title);
if (collapse[i]) {
GUILayout.Space(10);
t.trophyIcon = (Texture2D)EditorGUILayout.ObjectField("Icon", t.trophyIcon, typeof(Texture2D), false);
t.title = EditorGUILayout.TextField("Title", t.title);
t.grade = (TrophyGrade)EditorGUILayout.EnumPopup("Grade", t.grade);
t.details = EditorGUILayout.TextArea(t.details, GUILayout.Height(60));
}
}
}
EditorGUILayout.EndScrollView();
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Add")) {
trophyDB.trophiesList.Add(new Trophy());
collapse.Add(false);
}
if (GUILayout.Button("Remove")) {
trophyDB.trophiesList.RemoveAt(trophyDB.trophiesList.Count);
collapse.RemoveAt(collapse.Count);
}
EditorGUILayout.EndHorizontal();
}
}
Answer by Bunny83 · Dec 09, 2014 at 06:31 AM
At the moment you have a nexted loop which doesn't make much sense as you want one boolean for each trophy. You should do something like this:
// make sure we have as many booleans as we have trophies.
while (collapse.Count < trophyDB.trophiesList.Count)
collapse.Add(true); // expand by default
for (int i = 0; i < trophyDB.trophiesList.Count; ++i)
{
Trophy t = trophyDB.trophiesList[i];
collapse[i] = EditorGUILayout.Foldout(collapse[i], "Trophy: " + t.title);
if (collapse[i])
{
GUILayout.Space(10);
t.trophyIcon = (Texture2D)EditorGUILayout.ObjectField("Icon", t.trophyIcon, typeof(Texture2D), false);
t.title = EditorGUILayout.TextField("Title", t.title);
t.grade = (TrophyGrade)EditorGUILayout.EnumPopup("Grade", t.grade);
t.details = EditorGUILayout.TextArea(t.details, GUILayout.Height(60));
if (GUILayout.Button("Remove"))
{
trophyDB.trophiesList.RemoveAt(i);
collapse.RemoveAt(i);
EditorGUIUtility.ExitGUI(); // important to stop current GUI execution
}
}
}
I've added the remove button to the trophy itself so you can remove arbitrary items.
ps: Wouldn't it be more convinient to layout one trophy horizontally? I would probably go for:
IIIIII TTTTTTTTTTTT DDDDDDDDDDDD // I = image area
IIIIII GGGGGGGGGGGG DDDDDDDDDDDD // T = title
IIIIII RRRRRRRRRRRR DDDDDDDDDDDD // G = TrophyGrade dropdown
IIIIII DDDDDDDDDDDD // R = remove button
// D = details area
That wouldn't require foldouts at all ;)
The horizontal approach wasn't the way I wanted it to look aesthetically.
I used a for each as this approach worked at the time. Thanks for the help, going to try and implement it now ^^
EDIT:
Thanks, it works like a charm!