diff --git a/UnityGame/Assets/Editor/GameUI/UIComponentExportEditor.cs b/UnityGame/Assets/Editor/GameUI/UIComponentExportEditor.cs new file mode 100644 index 0000000..e0b2d33 --- /dev/null +++ b/UnityGame/Assets/Editor/GameUI/UIComponentExportEditor.cs @@ -0,0 +1,145 @@ +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) + { + var components = prefab.GetComponents(); + uguiComponentNames = prefab.GetComponents() + .Where(c => c != null && UIViewExportEditor.IsUGUIComponent(c)) + .Select(c => c.GetType().Name) + .Distinct() + .ToList(); + } + + 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} = 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(); + } +} \ No newline at end of file diff --git a/UnityGame/Assets/Editor/GameUI/UIComponentExportEditor.cs.meta b/UnityGame/Assets/Editor/GameUI/UIComponentExportEditor.cs.meta new file mode 100644 index 0000000..7ce0055 --- /dev/null +++ b/UnityGame/Assets/Editor/GameUI/UIComponentExportEditor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 75e425207f8b4c369bf1a58bd14d8cb4 +timeCreated: 1752945208 \ No newline at end of file diff --git a/UnityGame/Assets/Editor/GameUI/UIExportToolEditor.cs b/UnityGame/Assets/Editor/GameUI/UIViewExportEditor.cs similarity index 97% rename from UnityGame/Assets/Editor/GameUI/UIExportToolEditor.cs rename to UnityGame/Assets/Editor/GameUI/UIViewExportEditor.cs index 48d74d6..9fff607 100644 --- a/UnityGame/Assets/Editor/GameUI/UIExportToolEditor.cs +++ b/UnityGame/Assets/Editor/GameUI/UIViewExportEditor.cs @@ -8,8 +8,8 @@ using UnityEngine; using UnityEngine.UI; -[CustomEditor(typeof(UIExportTool))] -public class UIExportToolEditor : Editor +[CustomEditor(typeof(UIViewExport))] +public class UIViewExportEditor : Editor { private ReorderableList reorderableList; @@ -104,7 +104,7 @@ public class UIExportToolEditor : Editor /// /// 判断是否是常见UGUI组件(你可以自行扩展) /// - private bool IsUGUIComponent(Component component) + public static bool IsUGUIComponent(Component component) { return component is Graphic // 基类,包含 Image、Text、RawImage || component is Button diff --git a/UnityGame/Assets/Editor/GameUI/UIExportToolEditor.cs.meta b/UnityGame/Assets/Editor/GameUI/UIViewExportEditor.cs.meta similarity index 100% rename from UnityGame/Assets/Editor/GameUI/UIExportToolEditor.cs.meta rename to UnityGame/Assets/Editor/GameUI/UIViewExportEditor.cs.meta diff --git a/UnityGame/Assets/Scripts/GameLogic/UI/UILogic/UIComponentBase.cs b/UnityGame/Assets/Scripts/GameLogic/UI/UILogic/UIComponentBase.cs new file mode 100644 index 0000000..ab5f6ce --- /dev/null +++ b/UnityGame/Assets/Scripts/GameLogic/UI/UILogic/UIComponentBase.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +namespace CreatGame.UI +{ + /// + /// 通用的导出预制件的基类 + /// + public class UIComponentBase : MonoBehaviour + { + + } +} \ No newline at end of file diff --git a/UnityGame/Assets/Scripts/GameLogic/UI/UILogic/UIComponentBase.cs.meta b/UnityGame/Assets/Scripts/GameLogic/UI/UILogic/UIComponentBase.cs.meta new file mode 100644 index 0000000..59a25f4 --- /dev/null +++ b/UnityGame/Assets/Scripts/GameLogic/UI/UILogic/UIComponentBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ba52eedd767b46ae90e720030c75503f +timeCreated: 1752945611 \ No newline at end of file diff --git a/UnityGame/Assets/Scripts/GameLogic/UI/UIViewBase.cs b/UnityGame/Assets/Scripts/GameLogic/UI/UIViewBase.cs index 02064e6..b75f44e 100644 --- a/UnityGame/Assets/Scripts/GameLogic/UI/UIViewBase.cs +++ b/UnityGame/Assets/Scripts/GameLogic/UI/UIViewBase.cs @@ -16,7 +16,7 @@ namespace CreatGame.UI /// /// 导出脚本 /// - protected UIExportTool m_ExportTool; + protected UIViewExport MViewExport; /// /// 是否加载完成 /// @@ -27,7 +27,7 @@ namespace CreatGame.UI public virtual void PreLoad(GameObject viewObject) { m_ViewObject = viewObject; - m_ExportTool = viewObject.GetComponent(); + MViewExport = viewObject.GetComponent(); IsPreLoad = true; } /// @@ -47,11 +47,11 @@ namespace CreatGame.UI protected GameObject GetGameObject(string name) { - for (int i = 0; i < m_ExportTool.entries.Count; i++) + for (int i = 0; i < MViewExport.entries.Count; i++) { - if (m_ExportTool.entries[i].key == name) + if (MViewExport.entries[i].key == name) { - return m_ExportTool.entries[i].prefab; + return MViewExport.entries[i].prefab; } } diff --git a/UnityGame/Assets/Scripts/GameTools/UI/UIComponentExport.cs b/UnityGame/Assets/Scripts/GameTools/UI/UIComponentExport.cs new file mode 100644 index 0000000..2fd2689 --- /dev/null +++ b/UnityGame/Assets/Scripts/GameTools/UI/UIComponentExport.cs @@ -0,0 +1,19 @@ +using System; +using UnityEngine; +using System.Collections.Generic; + +namespace CreatGame.UI +{ + public class UIComponentExport : MonoBehaviour + { + [Serializable] + public class UIEntry + { + public string key; + public GameObject prefab; + public string selectedComponentName; // 存储选择的组件类型名 + } + + public List entries = new List(); + } +} \ No newline at end of file diff --git a/UnityGame/Assets/Scripts/GameTools/UI/UIComponentExport.cs.meta b/UnityGame/Assets/Scripts/GameTools/UI/UIComponentExport.cs.meta new file mode 100644 index 0000000..e67a8da --- /dev/null +++ b/UnityGame/Assets/Scripts/GameTools/UI/UIComponentExport.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d94101161a144f17b4b80530abe93975 +timeCreated: 1752945103 \ No newline at end of file diff --git a/UnityGame/Assets/Scripts/GameTools/UI/UIExportTool.cs b/UnityGame/Assets/Scripts/GameTools/UI/UIViewExport.cs similarity index 88% rename from UnityGame/Assets/Scripts/GameTools/UI/UIExportTool.cs rename to UnityGame/Assets/Scripts/GameTools/UI/UIViewExport.cs index 8c2f541..1c8fbc0 100644 --- a/UnityGame/Assets/Scripts/GameTools/UI/UIExportTool.cs +++ b/UnityGame/Assets/Scripts/GameTools/UI/UIViewExport.cs @@ -2,7 +2,7 @@ using System; using UnityEngine; using System.Collections.Generic; -public class UIExportTool : MonoBehaviour +public class UIViewExport : MonoBehaviour { [Serializable] public class UIEntry diff --git a/UnityGame/Assets/Scripts/GameTools/UI/UIExportTool.cs.meta b/UnityGame/Assets/Scripts/GameTools/UI/UIViewExport.cs.meta similarity index 100% rename from UnityGame/Assets/Scripts/GameTools/UI/UIExportTool.cs.meta rename to UnityGame/Assets/Scripts/GameTools/UI/UIViewExport.cs.meta diff --git a/UnityGame/UserSettings/Layouts/default-2022.dwlt b/UnityGame/UserSettings/Layouts/default-2022.dwlt index b4645f4..ec2d4f1 100644 --- a/UnityGame/UserSettings/Layouts/default-2022.dwlt +++ b/UnityGame/UserSettings/Layouts/default-2022.dwlt @@ -19,7 +19,7 @@ MonoBehaviour: width: 2048 height: 1060.8 m_ShowMode: 4 - m_Title: Project + m_Title: Inspector m_RootView: {fileID: 7} m_MinSize: {x: 875, y: 300} m_MaxSize: {x: 10000, y: 10000} @@ -41,7 +41,7 @@ MonoBehaviour: serializedVersion: 2 x: 0 y: 0 - width: 398.4 + width: 372 height: 358.80005 m_MinSize: {x: 231, y: 271} m_MaxSize: {x: 10001, y: 10021} @@ -74,7 +74,7 @@ MonoBehaviour: m_MinSize: {x: 200, y: 50} m_MaxSize: {x: 16192, y: 8096} vertical: 0 - controlID: 92 + controlID: 84 draggingID: 0 --- !u!114 &4 MonoBehaviour: @@ -91,9 +91,9 @@ MonoBehaviour: m_Children: [] m_Position: serializedVersion: 2 - x: 398.4 + x: 372 y: 0 - width: 1649.6 + width: 1676 height: 358.80005 m_MinSize: {x: 101, y: 121} m_MaxSize: {x: 4001, y: 4021} @@ -126,7 +126,7 @@ MonoBehaviour: m_MinSize: {x: 300, y: 100} m_MaxSize: {x: 24288, y: 16192} vertical: 1 - controlID: 91 + controlID: 83 draggingID: 0 --- !u!114 &6 MonoBehaviour: @@ -229,7 +229,7 @@ MonoBehaviour: m_MinSize: {x: 300, y: 50} m_MaxSize: {x: 24288, y: 8096} vertical: 0 - controlID: 38 + controlID: 48 draggingID: 0 --- !u!114 &10 MonoBehaviour: @@ -325,9 +325,9 @@ MonoBehaviour: m_Tooltip: m_Pos: serializedVersion: 2 - x: -1649.6 + x: -1676 y: 725.60004 - width: 1648.6 + width: 1675 height: 337.80005 m_SerializedDataModeController: m_DataMode: 0 @@ -376,9 +376,9 @@ MonoBehaviour: m_SceneHierarchy: m_TreeViewState: scrollPos: {x: 0, y: 0} - m_SelectedIDs: 0a5f0000 + m_SelectedIDs: 00600000 m_LastClickedID: 0 - m_ExpandedIDs: 0cfaffff + m_ExpandedIDs: 9e62ffff6e63ffff3c65ffff96beffff9cbeffffa4beffffbebeffffd2c5ffffd8c5ffffe0c5fffffac5ffffdcc7ffffe2c7ffffeac7ffff04c8ffff3eccffff44ccffff4cccffff66ccffff16d2ffff1cd2ffff24d2ffff3ed2ffffaee1ffffb4e1ffffbce1ffffd6e1ffffd0e4ffffe2e6ffff78e7ffff7ee7ffff86e7ffffa0e7ffffeeeeffff08efffff20efffff26efffff2eefffff2cfbfffff4ffffff4e5f00005e5f0000785f0000865f00008a5f00002863000038630000526300006063000064630000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -471,7 +471,7 @@ MonoBehaviour: serializedVersion: 2 x: -2048 y: 725.60004 - width: 397.4 + width: 371 height: 337.80005 m_SerializedDataModeController: m_DataMode: 0 @@ -494,7 +494,7 @@ MonoBehaviour: m_SkipHidden: 0 m_SearchArea: 1 m_Folders: - - Assets/Scripts/ThirdParty/LoopList/Runtime + - Assets/Scripts/GameTools m_Globs: [] m_OriginalText: m_ImportLogFlags: 0 @@ -510,7 +510,7 @@ MonoBehaviour: scrollPos: {x: 0, y: 0} m_SelectedIDs: b2df0000 m_LastClickedID: 57266 - m_ExpandedIDs: 00000000fc5f0000fe5f000000600000026000000460000006600000086000000a6000000c6000000e6000001060000012600000146000001660000018600000 + m_ExpandedIDs: 00000000ba5f0000bc5f0000be5f0000c05f0000c25f0000c45f0000c65f0000c85f0000ca5f0000cc5f0000 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -535,24 +535,24 @@ MonoBehaviour: m_Icon: {fileID: 0} m_ResourceFile: m_AssetTreeState: - scrollPos: {x: 0, y: 172.19995} + scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 - m_ExpandedIDs: ffffffff00000000ca5e0000d25e0000fc5f0000fe5f00000260000004600000066000000c6000000e60000054600000 + m_ExpandedIDs: ffffffff00000000ba5f0000be5f0000c05f0000c25f0000c45f0000c65f0000c85f0000ca5f0000cc5f0000f85f0000fc5f00005460000058600000ffffff7f m_RenameOverlay: m_UserAcceptedRename: 0 - m_Name: - m_OriginalName: + m_Name: MainView + m_OriginalName: MainView m_EditFieldRect: serializedVersion: 2 x: 0 y: 0 width: 0 height: 0 - m_UserData: 0 + m_UserData: 24592 m_IsWaitingForDelay: 0 m_IsRenaming: 0 - m_OriginalEventType: 11 + m_OriginalEventType: 0 m_IsRenamingFilename: 1 m_ClientGUIView: {fileID: 2} m_SearchString: @@ -634,7 +634,7 @@ MonoBehaviour: m_ShowGizmos: 0 m_TargetDisplay: 0 m_ClearColor: {r: 0, g: 0, b: 0, a: 0} - m_TargetSize: {x: 1920, y: 1080} + m_TargetSize: {x: 1280, y: 720} m_TextureFilterMode: 0 m_TextureHideFlags: 61 m_RenderIMGUI: 1 @@ -643,16 +643,16 @@ MonoBehaviour: m_VSyncEnabled: 0 m_Gizmos: 0 m_Stats: 0 - m_SelectedSizes: 03000000000000000000000000000000000000000000000000000000000000000000000000000000 + m_SelectedSizes: 07000000000000000000000000000000000000000000000000000000000000000000000000000000 m_ZoomArea: m_HRangeLocked: 0 m_VRangeLocked: 0 hZoomLockedByDefault: 0 vZoomLockedByDefault: 0 - m_HBaseRangeMin: -768 - m_HBaseRangeMax: 768 - m_VBaseRangeMin: -432 - m_VBaseRangeMax: 432 + m_HBaseRangeMin: -512 + m_HBaseRangeMax: 512 + m_VBaseRangeMin: -288 + m_VBaseRangeMax: 288 m_HAllowExceedBaseRangeMin: 1 m_HAllowExceedBaseRangeMax: 1 m_VAllowExceedBaseRangeMin: 1 @@ -672,7 +672,7 @@ MonoBehaviour: y: 21 width: 1051.6 height: 610 - m_Scale: {x: 0.6846354, y: 0.6846354} + m_Scale: {x: 1, y: 1} m_Translation: {x: 525.8, y: 305} m_MarginLeft: 0 m_MarginRight: 0 @@ -680,12 +680,12 @@ MonoBehaviour: m_MarginBottom: 0 m_LastShownAreaInsideMargins: serializedVersion: 2 - x: -768 - y: -445.49258 - width: 1536 - height: 890.98517 + x: -525.8 + y: -305 + width: 1051.6 + height: 610 m_MinimalGUI: 1 - m_defaultScale: 0.6846354 + m_defaultScale: 1 m_LastWindowPixelSize: {x: 1314.5, y: 788.75} m_ClearInEditMode: 1 m_NoCameraWarning: 1 @@ -1061,9 +1061,9 @@ MonoBehaviour: m_PlayAudio: 0 m_AudioPlay: 0 m_Position: - m_Target: {x: -3.6708412, y: -4.282875, z: 44.11006} + m_Target: {x: -3.4252472, y: 4.8869476, z: 122.382324} speed: 2 - m_Value: {x: 555.8997, y: 291.5927, z: -0.53083503} + m_Value: {x: -3.4252472, y: 4.8869476, z: 122.382324} m_RenderMode: 0 m_CameraMode: drawMode: 0 @@ -1101,7 +1101,7 @@ MonoBehaviour: m_Fade: m_Target: 0 speed: 2 - m_Value: 1 + m_Value: 0 m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} m_Pivot: {x: 0, y: 0, z: 0} m_Size: {x: 1, y: 1} @@ -1109,13 +1109,13 @@ MonoBehaviour: m_GridAxis: 1 m_gridOpacity: 0.5 m_Rotation: - m_Target: {x: -0.25270963, y: 0.65854186, z: -0.25104713, w: -0.6629036} + m_Target: {x: -0.15744555, y: 0.8125271, z: -0.25616828, w: -0.4993938} speed: 2 - m_Value: {x: 0, y: 0, z: 0, w: 1} + m_Value: {x: -0.1574451, y: 0.8125248, z: -0.25616753, w: -0.49939236} m_Size: - m_Target: 53.034447 + m_Target: 24.276482 speed: 2 - m_Value: 522.41943 + m_Value: 24.276482 m_Ortho: m_Target: 0 speed: 2 @@ -1133,7 +1133,7 @@ MonoBehaviour: m_FarClip: 10000 m_DynamicClip: 1 m_OcclusionCulling: 0 - m_LastSceneViewRotation: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} + m_LastSceneViewRotation: {x: -0.15744555, y: 0.8125271, z: -0.25616828, w: -0.4993938} m_LastSceneViewOrtho: 0 m_ReplacementShader: {fileID: 0} m_ReplacementString: