#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