using UnityEngine; using UnityEditor; /// /// 为 GridAndResourceDataAssets ScriptableObject 提供一个自定义的Inspector界面。 /// 主要功能是让列表元素的标题更具可读性。 /// [CustomEditor(typeof(GridAndResourceDataAssets))] public class GridAndResourceDrawer : Editor // Note: For this to work, your file must be named GridAndResourceDrawer.cs { private SerializedProperty terrainInfoListProp; private SerializedProperty resourceInfoListProp; private SerializedProperty wonderInfoListProp; private SerializedProperty mountainInfoProp; private SerializedProperty vegetationInfoProp; private void OnEnable() { // --- DEBUG START: OnEnable --- Debug.Log("[Custom Editor] OnEnable called. Attempting to find properties..."); terrainInfoListProp = serializedObject.FindProperty("TerrainInfoList"); if (terrainInfoListProp == null) Debug.LogError("[Custom Editor] FAILED to find property: 'TerrainInfoList'. Check spelling in GridAndResourceDataAssets.cs!"); resourceInfoListProp = serializedObject.FindProperty("ResourceInfoList"); if (resourceInfoListProp == null) Debug.LogError("[Custom Editor] FAILED to find property: 'ResourceInfoList'. Check spelling!"); wonderInfoListProp = serializedObject.FindProperty("WonderInfoList"); if (wonderInfoListProp == null) Debug.LogError("[Custom Editor] FAILED to find property: 'WonderInfoList'. Check spelling!"); mountainInfoProp = serializedObject.FindProperty("MountainInfo"); if (mountainInfoProp == null) Debug.LogError("[Custom Editor] FAILED to find property: 'MountainInfo'. Check spelling!"); vegetationInfoProp = serializedObject.FindProperty("VegetationInfo"); if (vegetationInfoProp == null) Debug.LogError("[Custom Editor] FAILED to find property: 'VegetationInfo'. Check spelling!"); Debug.Log("[Custom Editor] OnEnable finished property finding."); // --- DEBUG END: OnEnable --- } public override void OnInspectorGUI() { // --- DEBUG START: OnInspectorGUI --- // This log should appear spamming the console when you have the asset selected. // If it doesn't appear, the script isn't running at all. // Debug.Log("[Custom Editor] OnInspectorGUI is running..."); // --- DEBUG END: OnInspectorGUI --- serializedObject.Update(); EditorGUILayout.PropertyField(terrainInfoListProp, true); EditorGUILayout.PropertyField(mountainInfoProp, true); EditorGUILayout.PropertyField(vegetationInfoProp, true); EditorGUILayout.Space(10); DrawCustomList(resourceInfoListProp, "ResourceName", "Resource"); EditorGUILayout.Space(10); DrawCustomList(wonderInfoListProp, "Name", "Wonder"); serializedObject.ApplyModifiedProperties(); } private void DrawCustomList(SerializedProperty listProperty, string titleFieldName, string enumFieldName) { // 步骤1:手动绘制列表的折叠箭头和标题 // listProperty.displayName 是Unity自动获取的变量名(比如 "Resource Info List") // listProperty.isExpanded 存储了列表是否展开的状态,Foldout会根据用户点击来改变它 listProperty.isExpanded = EditorGUILayout.Foldout(listProperty.isExpanded, listProperty.displayName, true); // 步骤2:只有在列表展开时,才绘制其内容 if (listProperty.isExpanded) { // 增加缩进,让内容看起来在列表标题下面 EditorGUI.indentLevel++; // 步骤3:手动绘制列表的 "Size" 字段 EditorGUILayout.PropertyField(listProperty.FindPropertyRelative("Array.size")); // 步骤4:循环绘制每一个元素(这部分逻辑和之前一样,是正确的) for (int i = 0; i < listProperty.arraySize; i++) { SerializedProperty element = listProperty.GetArrayElementAtIndex(i); SerializedProperty titleProp = element.FindPropertyRelative(titleFieldName); string elementTitle; if (titleProp != null && !string.IsNullOrEmpty(titleProp.stringValue)) { elementTitle = titleProp.stringValue; } else { SerializedProperty enumProp = element.FindPropertyRelative(enumFieldName); if (enumProp != null && enumProp.propertyType == SerializedPropertyType.Enum) { elementTitle = $"{enumProp.enumDisplayNames[enumProp.enumValueIndex]} (Name not set)"; } else { elementTitle = $"Element {i}"; } } // 使用我们自定义的标题来绘制整个元素及其所有子属性 EditorGUILayout.PropertyField(element, new GUIContent(elementTitle), true); } // 恢复缩进 EditorGUI.indentLevel--; } } }