Files
CreatGame/UnityGame/Assets/Editor/GameUI/UIComponentExportEditor.cs

149 lines
5.7 KiB
C#
Raw Normal View History

2025-07-20 01:24:55 +08:00
using System.Linq;
2025-07-16 13:36:21 +08:00
using UnityEditor;
using UnityEngine;
2025-07-20 01:24:55 +08:00
using CreatGame.UI;
using UnityEditorInternal;
using Unity.VisualScripting;
using System.Collections.Generic;
2025-07-16 13:36:21 +08:00
2025-07-20 01:24:55 +08:00
[CustomEditor(typeof(UIComponentExport))]
public class UIComponentExportEditor : Editor
2025-07-16 13:36:21 +08:00
{
private ReorderableList reorderableList;
2025-07-16 18:10:09 +08:00
private void InitReorderableList()
2025-07-16 13:36:21 +08:00
{
reorderableList = new ReorderableList(
serializedObject,
serializedObject.FindProperty("entries"),
true, true, true, true);
2025-07-20 01:24:55 +08:00
reorderableList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "UI Prefab Entries"); };
2025-07-16 13:36:21 +08:00
2025-07-20 01:24:55 +08:00
reorderableList.elementHeightCallback = (int index) => { return EditorGUIUtility.singleLineHeight + 6f; };
2025-07-16 13:36:21 +08:00
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<string> uguiComponentNames = new List<string>();
if (prefab != null)
{
uguiComponentNames = prefab.GetComponents<Component>()
2025-07-20 01:24:55 +08:00
.Where(c => c != null && UIViewExportEditor.IsUGUIComponent(c))
2025-07-16 13:36:21 +08:00
.Select(c => c.GetType().Name)
.Distinct()
.ToList();
2025-07-24 16:04:27 +08:00
if (uguiComponentNames.Count == 0)
{
uguiComponentNames.Add("GameObject");
}
2025-07-16 13:36:21 +08:00
}
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();
2025-07-16 18:10:09 +08:00
if (reorderableList == null)
{
InitReorderableList();
}
reorderableList?.DoLayoutList();
2025-07-16 13:36:21 +08:00
serializedObject.ApplyModifiedProperties();
2025-07-16 18:10:09 +08:00
if (GUILayout.Button("导出代码"))
{
ExportCode();
}
2025-07-16 13:36:21 +08:00
}
2025-07-16 18:10:09 +08:00
/// <summary>
/// 导出代码
/// </summary>
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("{");
2025-07-20 01:24:55 +08:00
sb.AppendLine($" public partial class {className} : UIComponentBase");
2025-07-16 18:10:09 +08:00
sb.AppendLine(" {");
2025-07-16 18:22:32 +08:00
sb.AppendLine($" public override string PrefabPath => \"Prefabs/UI/{target.GameObject().name}\";");
2025-07-16 18:10:09 +08:00
// 字段定义
for (int i = 0; i < reorderableList.count; i++)
{
SerializedProperty element = reorderableList.serializedProperty.GetArrayElementAtIndex(i);
sb.AppendLine(" /// <summary>");
sb.AppendLine(" /// ");
sb.AppendLine(" /// </summary>");
2025-07-16 18:12:25 +08:00
sb.AppendLine($" public {element.FindPropertyRelative("selectedComponentName").stringValue} {element.FindPropertyRelative("key").stringValue};");
2025-07-16 18:10:09 +08:00
}
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} = 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();
}
2025-07-16 13:36:21 +08:00
}