Unity嵌套列表自定义编辑器开发:动态调整子列表及弹窗问题
Fixing Nested List Issues in Unity Custom Editor
Got it, let's tackle these two problems one by one—they’re both rooted in not tying state (like sublist expansion and popup selection) to individual sublist items, instead relying on global variables in your editor script. Here’s how to fix this properly:
1. First: Define a Serializable Nested Data Structure
You need each sublist item to track its own unique state. Create a serializable class for your nested items that includes:
- The sublist content itself
- A boolean to control if the sublist is expanded (this controls its visible "size" in the editor)
- An integer to store the selected popup index for that specific item
using UnityEngine; using System.Collections.Generic; [System.Serializable] public class NestedListItem { // Your sublist content (customize this to match your data needs) public List<string> subItems = new List<string>(); // Tracks if this item's sublist is expanded/collapsed (controls visible size) public bool isExpanded = false; // Stores the selected popup index for THIS item alone public int selectedOptionIndex = 0; // Popup options (can be static or dynamic—adjust as needed for your use case) public string[] popupOptions = new string[] { "Option A", "Option B", "Option C" }; } // Your main MonoBehaviour that holds the top-level list public class NestedListHolder : MonoBehaviour { public List<NestedListItem> topLevelList = new List<NestedListItem>(); }
2. Build the Custom Editor with Per-Item State
Now, in your editor script, use SerializedProperty to access each item’s individual state. This ensures every sublist’s expansion and popup selection are fully independent.
using UnityEditor; using UnityEngine; [CustomEditor(typeof(NestedListHolder))] public class NestedListEditor : Editor { private SerializedProperty topLevelList; private void OnEnable() { // Get the serialized property for the top-level list topLevelList = serializedObject.FindProperty("topLevelList"); } public override void OnInspectorGUI() { serializedObject.Update(); // Draw the top-level list header with default add/remove controls EditorGUILayout.PropertyField(topLevelList, true); // Iterate over each top-level item to customize the sublist UI for (int i = 0; i < topLevelList.arraySize; i++) { SerializedProperty currentItem = topLevelList.GetArrayElementAtIndex(i); // Get references to the item's unique state properties SerializedProperty isExpanded = currentItem.FindPropertyRelative("isExpanded"); SerializedProperty selectedOption = currentItem.FindPropertyRelative("selectedOptionIndex"); SerializedProperty popupOptions = currentItem.FindPropertyRelative("popupOptions"); SerializedProperty subItems = currentItem.FindPropertyRelative("subItems"); // Foldout to control sublist expansion (fixes the size sync issue) isExpanded.boolValue = EditorGUILayout.Foldout(isExpanded.boolValue, $"List Item {i+1}"); if (isExpanded.boolValue) { // Popup bound to THIS item's selected index (fixes global selection issue) selectedOption.intValue = EditorGUILayout.Popup( "Select Option", selectedOption.intValue, popupOptions.stringValue ); // Draw the sublist with its own nested add/remove controls EditorGUI.indentLevel++; EditorGUILayout.PropertyField(subItems, true); EditorGUI.indentLevel--; } EditorGUILayout.Space(); } serializedObject.ApplyModifiedProperties(); } }
Key Fixes Explained
- Independent Sublist Sizes: By storing
isExpandedon eachNestedListItem, we control visibility per-item—no more global expansion state affecting all sublists at once. - Per-Item Popup Selection: The
selectedOptionIndexis tied directly to each individual item, so selecting an option in one sublist won’t overwrite selections in others. The Popup control uses this item-specific index instead of a global variable.
Extra Tips
- If your popup options need to be dynamic (e.g., loaded from a ScriptableObject or resource), move the options array to a static field in your editor script or populate it in
OnEnable()—just make sure each item’s selection index remains stored per-item. - For more complex sublist items, you can create a custom
PropertyDrawerforNestedListItemto clean up the editor code and reuse the UI logic elsewhere.
内容的提问来源于stack exchange,提问作者Wyrncael
相关产品推荐
相关产品推荐

