using System.Linq; using UnityEditor; using UnityEngine; using CreatGame.UI; using UnityEditorInternal; using Unity.VisualScripting; using System.Collections.Generic; [CustomEditor(typeof(UIComponentExport))] public class UIComponentExportEditor : Editor { private ReorderableList reorderableList; private void InitReorderableList() { reorderableList = new ReorderableList( serializedObject, serializedObject.FindProperty("entries"), true, true, true, true); reorderableList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "UI Prefab Entries"); }; reorderableList.elementHeightCallback = (int index) => { return EditorGUIUtility.singleLineHeight + 6f; }; reorderableList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(index); // drawElementCallback 中的内容 SerializedProperty keyProp = element.FindPropertyRelative("key"); SerializedProperty prefabProp = element.FindPropertyRelative("prefab"); SerializedProperty selectedNameProp = element.FindPropertyRelative("selectedComponentName"); GameObject prefab = prefabProp.objectReferenceValue as GameObject; // 查找组件类型 List uguiComponentNames = new List(); if (prefab != null) { uguiComponentNames = prefab.GetComponents() .Where(c => c != null && UIViewExportEditor.IsUGUIComponent(c)) .Select(c => c.GetType().Name) .Distinct() .ToList(); if (uguiComponentNames.Count == 0) { uguiComponentNames.Add("GameObject"); } } float lineHeight = EditorGUIUtility.singleLineHeight; float padding = 4f; float thirdWidth = (rect.width - 2 * padding) / 3f; Rect keyRect = new Rect(rect.x, rect.y + 2, thirdWidth, lineHeight); Rect prefabRect = new Rect(rect.x + thirdWidth + padding, rect.y + 2, thirdWidth, lineHeight); Rect popupRect = new Rect(rect.x + 2 * (thirdWidth + padding), rect.y + 2, thirdWidth, lineHeight); // key 字段 EditorGUI.PropertyField(keyRect, keyProp, GUIContent.none); // prefab 字段 EditorGUI.PropertyField(prefabRect, prefabProp, GUIContent.none); // 下拉框 if (uguiComponentNames.Count > 0) { int selectedIndex = Mathf.Max(0, uguiComponentNames.IndexOf(selectedNameProp.stringValue)); selectedIndex = EditorGUI.Popup(popupRect, selectedIndex, uguiComponentNames.ToArray()); selectedNameProp.stringValue = uguiComponentNames[selectedIndex]; } else { EditorGUI.LabelField(popupRect, "无UGUI组件"); } }; } public override void OnInspectorGUI() { serializedObject.Update(); if (reorderableList == null) { InitReorderableList(); } reorderableList?.DoLayoutList(); serializedObject.ApplyModifiedProperties(); if (GUILayout.Button("导出代码")) { ExportCode(); } } /// /// 导出代码 /// private void ExportCode() { string savePath = Application.dataPath + "/Scripts/GameLogic/Export/UGUI/"; if (string.IsNullOrEmpty(savePath)) return; string className = $"UI{target.GameObject().name}"; string filename = System.IO.Path.Combine(savePath, $"{className}.cs"); var sb = new System.Text.StringBuilder(); sb.AppendLine("using UnityEngine;"); sb.AppendLine("using UnityEngine.UI;"); sb.AppendLine(); sb.AppendLine("namespace CreatGame.UI"); sb.AppendLine("{"); sb.AppendLine($" public partial class {className} : UIComponentBase"); sb.AppendLine(" {"); // sb.AppendLine($" public override string PrefabPath => \"Prefabs/UI/{target.GameObject().name}\";"); // 字段定义 for (int i = 0; i < reorderableList.count; i++) { SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(i); sb.AppendLine(" /// "); sb.AppendLine(" /// "); sb.AppendLine(" /// "); sb.AppendLine($" public {element.FindPropertyRelative("selectedComponentName").stringValue} {element.FindPropertyRelative("key").stringValue};"); } sb.AppendLine(" public override void PreLoad(GameObject view)"); sb.AppendLine(" {"); sb.AppendLine(" base.PreLoad(view);"); sb.AppendLine(); for (int i = 0; i < reorderableList.count; i++) { SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(i); var filedName = element.FindPropertyRelative("key").stringValue; var typeName = element.FindPropertyRelative("selectedComponentName").stringValue; sb.AppendLine($" {filedName} = m_ViewExport.GetGameObject(nameof({filedName})).GetComponent<{typeName}>();"); } sb.AppendLine(" }"); sb.AppendLine(" }"); sb.AppendLine("}"); Debug.Log(sb.ToString()); System.IO.File.WriteAllText(filename, sb.ToString()); Debug.Log($"✅ 导出成功:{filename}"); AssetDatabase.Refresh(); } }