#if !BUILDING using Cysharp.Threading.Tasks; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.UI; namespace EditorCreateUI { public partial class Editor_CreateUIPanel : EditorWindowBase { private GenerateAttData[] generateAttDatas = new GenerateAttData[] { new GenerateAttData("Ga_", "对象", "GameObject"), new GenerateAttData("Tr_", "对象", "Transform"), new GenerateAttData("Rect_", "RectTransform", "RectTransform"), new GenerateAttData("Content_", "容器", "Transform"), new GenerateAttData("Btn_", "按钮", "Button"), new GenerateAttData("Tcg_", "复选框组", "TgCheckGroup"), new GenerateAttData("Av_", "视频ui", "DisplayUGUI", "using RenderHeads.Media.AVProVideo;"), new GenerateAttData("Tx_", "文本", "TextMeshProUGUI", "using TMPro;"), new GenerateAttData("Img_", "图片", "Image或RawImage"), new GenerateAttData("Sr_", "滑动列表", "ScrollRect"), new GenerateAttData("Rv_", "无限列表", "RecycleView"), new GenerateAttData("Ev_", "无限列表(带标签)", "ExpandableView"), new GenerateAttData("Evs_", "无限列表(带标签,单二级)", "ExpandableViewSingle"), new GenerateAttData("Input_", "输入框", "TMP_InputField", "using TMPro;"), new GenerateAttData("Slider_", "滑动条", "Slider"), new GenerateAttData("Toggle_", "复选框", "Toggle"), new GenerateAttData("TG_", "复选组", "TgGroup"), new GenerateAttData("Lt_", "多语言文本", "LanguageText"), new GenerateAttData("Li_", "多语言图片", "LanguageImage"), new GenerateAttData("Ldt_", "倒计时", "LanguageDownTime"), new GenerateAttData("Tm_", "TMP文本", "TextMeshProUGUI", "using TMPro;"), new GenerateAttData("Cam_", "摄像机", "Camera"), new GenerateAttData("Class_{T}", "自定义类型", "{T}"), }; private static string[] notClose_raycast = new string[] { "Scroll View", "btn_", "ray", "sv_", "close", }; private static string[] notFindChild = new string[] { "UI_" }; private string panelName = ""; private int selectedOptionIndex = 0; private Vector2 scrollPosition = Vector2.zero; string systemName; /// /// child, panelName, prefabDir /// List> lastPanelName = new List>(); int lastPanelIndex = 0; [MenuItem("Window/Create UI Panel")] public static void ShowWindow() { var window = EditorWindow.GetWindow(typeof(Editor_CreateUIPanel)); window.titleContent = new GUIContent("UI管理工具"); } private void ShowTips() { try { if (position.width <= 350) return; //GUILayout.Label("首字母大写,前缀_名称。会自动创建变量。\n不是以下类型前缀的,都自动生成为Transform。\n名称中带ray不会关闭RayCast"); scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, true, GUILayout.ExpandHeight(true)); // 开始绘制表格布局 GUILayout.BeginVertical(GUI.skin.box); // 表头 GUILayout.BeginHorizontal(); DrawTableCell("", 20, 20, Color.gray); DrawTableCell("前缀", 150, 20, Color.gray); DrawTableCell("类型", 150, 20, Color.gray); DrawTableCell("描述", 150, 20, Color.gray); GUILayout.EndHorizontal(); // 分隔线 DrawHorizontalLine(500); // 数据行 for (int i = 0; i < generateAttDatas.Length; i++) { var data = generateAttDatas[i]; GUILayout.BeginHorizontal(); DrawTableCell((i + 1).ToString(), 20, 15, Color.gray); DrawTableCell(data.prefix, 150); DrawTableCell(data.type, 150); DrawTableCell(data.description, 150); GUILayout.EndHorizontal(); // 添加淡淡的分割线 DrawHorizontalLine(500, Color.gray); } // 结束绘制表格布局 GUILayout.EndVertical(); // 结束绘制滚动视图 GUILayout.EndScrollView(); } catch (Exception) { } } bool CheckIsThis() { var sta = PrefabStageUtility.GetCurrentPrefabStage(); if (sta && sta.prefabContentsRoot) { if (sta.prefabContentsRoot.name == panelName) { return true; } } return false; } bool GetIsSingle() { var sta = PrefabStageUtility.GetCurrentPrefabStage(); Debug.Log(sta.prefabContentsRoot); return true; } string[] GetCompletion() { List str = new List(); // 指定目录 string directoryPath = "Assets/Scripts/HotUpdate/Game/UI"; DirectoryInfo directoryInfo = new DirectoryInfo(directoryPath); DirectoryInfo[] di = directoryInfo.GetDirectories(); for (int i = 0; i < di.Length; i++) { DirectoryInfo[] di2 = di[i].GetDirectories(); for (int j = 0; j < di2.Length; j++) { str.Add(di2[j].Name); GetCompletion(ref str, di2[j]); } } return str.ToArray(); } void GetCompletion(ref List str, DirectoryInfo dir) { DirectoryInfo[] dirs = dir.GetDirectories(); for (int i = 0; i < dirs.Length; i++) { var item = dirs[i]; if (item.Name.ToLower().StartsWith("ui_")) { str.Add(item.Name); GetCompletion(ref str, item); } } } private void OnGUI() { //try //{ //// 页签名称数组 //string[] tabNames = { "Main", "Child" }; //// 创建一个横向页签栏 //selectedTabIndex = GUILayout.Toolbar(selectedTabIndex, tabNames); if (IsCreateChild == false) OnMainGUI(); else OnCreateChildGUI(); //if (GUI_Button("测试")) // GetCompletion(); GUILayout.Space(20); // 开始绘制滚动视图 ShowTool(); ShowTips(); //} //catch (Exception) //{ //} } private void CreatePanel(string systemName) { string panelName = this.panelName; if (!this.panelName.StartsWith("UI_")) panelName = "UI_" + this.panelName; // 复制 UI_Example 目录 string sourceDir = "Assets/Art/UI/Panels/UI_Example"; string targetDir = "Assets/Art/UI/Panels/" + panelName; if (!AssetDatabase.IsValidFolder(targetDir)) { AssetDatabase.CopyAsset(sourceDir, targetDir); AssetDatabase.Refresh(); } else { Debug.LogWarning("已存在同名的面板。"); return; } // 将 UI_Example 文件复制到新目录 string sourceFile = Path.Combine(sourceDir, "UI_Example.prefab"); string destFile = Path.Combine(targetDir, panelName + ".prefab"); string deleteFile = Path.Combine(targetDir, "UI_Example.prefab"); File.Copy(sourceFile, destFile); File.Delete(deleteFile); string ToSourceFolder = $"Assets/Scripts/HotUpdate/Game/UI/{systemName}/{panelName}"; if (!Directory.Exists(ToSourceFolder)) Directory.CreateDirectory(ToSourceFolder); AssetDatabase.Refresh(); //复制 UI_Example.cs 脚本并创建新脚本 string scriptSource = $"Assets/Scripts/HotUpdate/Game/UI/Normal/UI_Example/UI_Example.cs"; string scriptTarget = $"Assets/Scripts/HotUpdate/Game/UI/{systemName}/{panelName}/{panelName}.cs"; AssetDatabase.CopyAsset(scriptSource, scriptTarget); // 复制 UI_Example_Generate.cs 脚本并创建新脚本 string scriptSource2 = $"Assets/Scripts/HotUpdate/Game/UI/Normal/UI_Example/UI_Example_Generate.cs"; string scriptTarget2 = $"Assets/Scripts/HotUpdate/Game/UI/{systemName}/{panelName}/{panelName}_Generate.cs"; AssetDatabase.CopyAsset(scriptSource2, scriptTarget2); // 读取并替换脚本内容 string scriptPath = Path.Combine(Application.dataPath, $"Scripts/HotUpdate/Game/UI/{systemName}/{panelName}/{panelName}.cs"); string scriptContent = File.ReadAllText(scriptPath); scriptContent = scriptContent.Replace("UI_Example", panelName); // 将修改后的内容写回脚本文件 File.WriteAllText(scriptPath, scriptContent); // 读取并替换脚本内容 string scriptPath2 = Path.Combine(Application.dataPath, $"Scripts/HotUpdate/Game/UI/{systemName}/{panelName}/{panelName}_Generate.cs"); string scriptContent2 = File.ReadAllText(scriptPath2); scriptContent2 = scriptContent2.Replace("UI_Example", panelName); // 将修改后的内容写回脚本文件 File.WriteAllText(scriptPath2, scriptContent2); AssetDatabase.Refresh(); GameObject prefab = AssetDatabase.LoadAssetAtPath(destFile); if (prefab != null) { // 修改 tx_name 的文本属性 //Text textComponent = prefab.GetComponentInChildren(); //if (textComponent != null) // textComponent.text = panelName.Substring(3); //else // Debug.LogError("在预制体中未找到 Text 组件。"); // 保存预制体的更改 PrefabUtility.SaveAsPrefabAsset(prefab, destFile); var sceneView = SceneView.sceneViews[0] as SceneView; // 激活主场景视图 if (sceneView != null) sceneView.Focus(); Selection.activeObject = prefab; AssetDatabase.OpenAsset(prefab); if (!SceneView.lastActiveSceneView.in2DMode) // 切换到 2D 模式 SceneView.lastActiveSceneView.in2DMode = true; } else { //Debug.LogError("在路径 " + destFile + " 中未找到预制体。"); } AssetDatabase.Refresh(); } bool IsSpecialName(string name) { return char.IsUpper(name[0]) && name.Contains("_") && !name.Contains(" ") && !name.Contains("(") && !name.Contains(")"); } void AutoSetRaycast(Transform tr) { bool isNot = false; for (int i = 0; i < notClose_raycast.Length; i++) { if (tr.name.ToLower().Contains(notClose_raycast[i].ToLower())) { isNot = true; break; } } if (!isNot) { //如果不是特殊命名 if (!IsSpecialName(tr.name)) { var gra = tr.GetComponent(); if (gra != null) gra.raycastTarget = false; } else { //Text都关掉 Raycast var te = tr.GetComponent(); if (te != null) te.raycastTarget = false; } } for (int k = 0; k < tr.childCount; k++) AutoSetRaycast(tr.GetChild(k)); } void GenerateAttribute(string systemName) { string panelName = this.panelName; if (!this.panelName.StartsWith("UI_")) panelName = "UI_" + this.panelName; string targetDir = "Assets/Art/UI/Panels/" + panelName; string destFile = Path.Combine(targetDir, panelName + ".prefab"); string str = @"using UnityEngine; using UnityEngine.UI; [USING] //子类[NAME] [UIClassName(typeof([NAME]))] public abstract class [NAME]_Generate : UIRootPanelBase { [ATTRIBUTE] protected abstract void Init(); internal override void InitAttribute() { [FIND] Init(); } }"; str = str.Replace("[NAME]", panelName); GameObject prefab = AssetDatabase.LoadAssetAtPath(destFile); List> tuples = new List>(); string str_using = ""; Action action = null; action = (tr) => { // 检查节点名字首字母是否为大写,并且带_ if (IsSpecialName(tr.name)) { Transform target = tr.parent; string namePath = tr.name; while (target != prefab.transform) { namePath = target.name + "/" + namePath; target = target.parent; } //Debug.Log("生成:" + tr.name); string attStr; string findStr; if (tr.name.StartsWith("Img_")) { if (tr.GetComponent() != null) { attStr = "internal RawImage " + tr.name + ";"; findStr = $"{tr.name} = transform.Find(\"{namePath}\").GetComponent();"; } else if (tr.GetComponent() != null) { attStr = "internal Image " + tr.name + ";"; findStr = $"{tr.name} = transform.Find(\"{namePath}\").GetComponent();"; } else { attStr = "internal Transform " + tr.name + ";"; findStr = $"{tr.name} = transform.Find(\"{namePath}\");"; } } else if (tr.name.StartsWith("Btn_")) { if (tr.GetComponent