515 lines
16 KiB
C#
515 lines
16 KiB
C#
|
/*
|
||
|
--- 创建人: zjy
|
||
|
--- 描 述: 导出UI控制脚本. UI控件需要安装标准命名
|
||
|
*/
|
||
|
|
||
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
//using System.Globalization;
|
||
|
//using System.Text.RegularExpressions;
|
||
|
using System.IO;
|
||
|
using System.Text;
|
||
|
using TMPro;
|
||
|
using Unity.Plastic.Newtonsoft.Json.Linq;
|
||
|
using UnityEditor;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.UI;
|
||
|
|
||
|
|
||
|
public class GoInfo
|
||
|
{
|
||
|
public string AllPath;
|
||
|
public string TypeName; //类型名称
|
||
|
public string FullName; //全名
|
||
|
public GameObject go;
|
||
|
}
|
||
|
|
||
|
|
||
|
public class UIExportTool : Editor
|
||
|
{
|
||
|
|
||
|
public static string ScriptName;
|
||
|
public static string ScriptDir;
|
||
|
public static string UIScriptRootPath = UnityEngine.Application.dataPath + "/Scripts/UI"; // UI 脚本生成根目录
|
||
|
|
||
|
public static readonly string UIPrefabRootPath = "Assets/GameAssets/Prefabs/UI"; // UI Prefab根目录
|
||
|
public static readonly string UIPathConfigFile = "Assets/GameAssets/TextAssets/UIMgrPath.json"; // UI Prefab资源路径文件名
|
||
|
|
||
|
/// <summary>
|
||
|
/// 在Project下右键创建
|
||
|
/// </summary>
|
||
|
[MenuItem("Assets/创建UI脚本", false, -99)]
|
||
|
public static void ProCreateLua()
|
||
|
{
|
||
|
string allPath = AssetDatabase.GetAssetPath(Selection.activeGameObject);
|
||
|
//先替换成lua后缀
|
||
|
allPath = allPath.Replace(".prefab", ".cs");
|
||
|
string[] patharr = allPath.Split('/');
|
||
|
if (patharr.Length > 2)
|
||
|
{
|
||
|
//固定路径
|
||
|
ScriptDir = UIScriptRootPath + "/" + patharr[patharr.Length - 2];
|
||
|
ScriptName = patharr[patharr.Length - 1];
|
||
|
}
|
||
|
|
||
|
Debug.Log("开始生成:" + ScriptDir + "/" + ScriptName);
|
||
|
OnCreateBehaviour(Selection.activeGameObject.transform);
|
||
|
}
|
||
|
|
||
|
|
||
|
public static void OnCreateBehaviour(Transform ptf)
|
||
|
{
|
||
|
if (string.IsNullOrEmpty(ScriptName))
|
||
|
{
|
||
|
Debug.LogWarning("OnCreateBehaviour. string.IsNullOrEmpty(ScriptName). 先把设置文件名");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
List<GoInfo> objs = new List<GoInfo>();
|
||
|
foreach (var tf in ptf.GetComponentsInChildren<Transform>(true))
|
||
|
{
|
||
|
if (tf == ptf)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
string goname = tf.gameObject.name;
|
||
|
// Debug.Log(allPath);
|
||
|
GoInfo goinfo = new GoInfo();
|
||
|
goinfo.go = tf.gameObject;
|
||
|
goinfo.AllPath = GetAllPath(tf, ptf);
|
||
|
if (ComponentCanGrae(goname, tf, goinfo))
|
||
|
{
|
||
|
objs.Add(goinfo);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (objs.Count == 0)
|
||
|
{
|
||
|
Debug.LogError("UI命名不规范|未找到需要导出的控件. 请自行创建");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!Directory.Exists(ScriptDir))
|
||
|
{
|
||
|
Directory.CreateDirectory(ScriptDir);
|
||
|
}
|
||
|
|
||
|
string filePath = ScriptDir + "/" + ScriptName;
|
||
|
Debug.Log("导出目录 filePath:" + filePath);
|
||
|
if (!File.Exists(filePath))
|
||
|
{
|
||
|
CreateFile(objs);
|
||
|
Debug.Log("导出成功 filePath:" + filePath);
|
||
|
ExportUIPath();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//文件存在替换文件
|
||
|
ReplaceFile(objs);
|
||
|
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 文件不存在的时候创建文件
|
||
|
/// </summary>
|
||
|
/// <param name="objs"></param>
|
||
|
private static void CreateFile(List<GoInfo> objs)
|
||
|
{
|
||
|
// Debug.Log("创建脚本");
|
||
|
UIExportTextBuilder bs = new UIExportTextBuilder(objs, Selection.activeGameObject.name);
|
||
|
bs.BuildFileAllStr();
|
||
|
byte[] buf = Encoding.UTF8.GetBytes(bs.AllStr.ToString());
|
||
|
File.WriteAllBytes(bs.filePath, buf);
|
||
|
AssetDatabase.SaveAssets();
|
||
|
AssetDatabase.Refresh();
|
||
|
Debug.Log("创建脚本完成. 路径:" + bs.filePath);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 文件存在的时候替换文件
|
||
|
/// </summary>
|
||
|
/// <param name="objs"></param>
|
||
|
private static void ReplaceFile(List<GoInfo> objs)
|
||
|
{
|
||
|
//Debug.Log("已有文本");
|
||
|
UIExportTextBuilder bs = new UIExportTextBuilder(objs, ScriptName);
|
||
|
bs.ReplaceFile();
|
||
|
AssetDatabase.SaveAssets();
|
||
|
AssetDatabase.Refresh();
|
||
|
Debug.Log("已替换旧文件标签内内容. filePath:" + bs.filePath);
|
||
|
}
|
||
|
|
||
|
public static string GetAllPath(Transform tf, Transform ptf)
|
||
|
{
|
||
|
string name = tf.gameObject.name;
|
||
|
Transform temp = tf.parent;
|
||
|
while (temp != null && temp != ptf)
|
||
|
{
|
||
|
name = temp.name + "/" + name;
|
||
|
temp = temp.parent;
|
||
|
}
|
||
|
|
||
|
return name;
|
||
|
}
|
||
|
|
||
|
|
||
|
// TestUI // 界面预制体
|
||
|
// TestUI.lua.txt // 界面脚本
|
||
|
// TestUnit // 界面单元格
|
||
|
// TestUnit.lua.txt // 界面单元格脚本
|
||
|
// TestCtrl // 预制体
|
||
|
// TestCtrl.lua.txt // 预制体控制脚本
|
||
|
//
|
||
|
// UI控件简写
|
||
|
// Text: txtTest // 文本
|
||
|
// Text: txtTest // 文本
|
||
|
// Image: imgTest // 精灵图片
|
||
|
// RawImage: rimgTest // 大图
|
||
|
// Button: btnTest // 按钮
|
||
|
// InputField: iptTest // 输入框
|
||
|
// Transform: tfTest // 坐标变幻
|
||
|
// RectTransform: rtfTest // 坐标变幻
|
||
|
// GameObject: goTest // 对象
|
||
|
// Panel: plTest // 面板,容器
|
||
|
// ScrollView|ScrollRect: svTest // 滑动列表
|
||
|
// SupperScrollView: ssvTest // 超级滑动列表
|
||
|
// Toggle: tglTest // 选择框
|
||
|
// ToggleGroup: tglgTest // 选择组
|
||
|
// Slider: sldTest // 滑动条
|
||
|
// Dropdown: ddTest // 下拉选择框
|
||
|
// UIInputNumChange: numc //数字变化组件
|
||
|
|
||
|
// TextMeshProUGUI: 例如 tmpTest //TMP文本 tmp
|
||
|
// TMP_InputField: 例如 tiptTest //TMP文本输入框 tipt
|
||
|
// TMP_Dropdown: 例如 tddTest //TMP下拉框
|
||
|
|
||
|
// UICurBgLeft: uibglTest //标题居左大
|
||
|
// UICurBgMiddle: uibgmTest //标题居中大
|
||
|
// UICurBgFullScreen: uibgfTest //全屏
|
||
|
// UICurBgSmall: uibgsTest //标题居中小
|
||
|
// UICurBgMiddle: uibgmtTest //弹窗
|
||
|
|
||
|
// UIRoleRawImage: rriTest // 角色模型
|
||
|
// UIItemIconList: iilTest // 道具列表
|
||
|
|
||
|
public static bool ComponentCanGrae(string goname, Transform tf, GoInfo goinfo)
|
||
|
{
|
||
|
if (goname.StartsWith("tf"))
|
||
|
{
|
||
|
TipHasComponent<Transform>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("rtf"))
|
||
|
{
|
||
|
TipHasComponent<RectTransform>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("go"))
|
||
|
{
|
||
|
TipHasComponent<GameObject>(goname, tf, goinfo);
|
||
|
goinfo.TypeName = "GameObject";
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("pl"))
|
||
|
{
|
||
|
TipHasComponent<Image>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("sv"))
|
||
|
{
|
||
|
TipHasComponent<ScrollRect>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("rimg"))
|
||
|
{
|
||
|
TipHasComponent<RawImage>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("img"))
|
||
|
{
|
||
|
TipHasComponent<Image>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("tglg"))
|
||
|
{
|
||
|
TipHasComponent<ToggleGroup>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("tgl"))
|
||
|
{
|
||
|
TipHasComponent<Toggle>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("sld"))
|
||
|
{
|
||
|
TipHasComponent<Slider>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("sclb"))
|
||
|
{
|
||
|
TipHasComponent<Scrollbar>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("txt"))
|
||
|
{
|
||
|
TipHasComponent<Text>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (goname.StartsWith("btn"))
|
||
|
{
|
||
|
TipHasComponent<Button>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("ipt"))
|
||
|
{
|
||
|
TipHasComponent<InputField>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("dd"))
|
||
|
{
|
||
|
TipHasComponent<Dropdown>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("numc"))
|
||
|
{
|
||
|
TipHasComponent<UIInputNumChange>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("tmp"))
|
||
|
{
|
||
|
TipHasComponent<TextMeshProUGUI>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("tipt"))
|
||
|
{
|
||
|
TipHasComponent<TMP_InputField>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (goname.StartsWith("tdd"))
|
||
|
{
|
||
|
TipHasComponent<TMP_Dropdown>(goname, tf, goinfo);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//if (goname.StartsWith("uibgl"))
|
||
|
//{
|
||
|
// TipHasComponent<UICurBgLeft>(goname, tf, goinfo);
|
||
|
// return true;
|
||
|
//}
|
||
|
|
||
|
//if (goname.StartsWith("uibgm"))
|
||
|
//{
|
||
|
// TipHasComponent<UICurBgMiddle>(goname, tf, goinfo);
|
||
|
// return true;
|
||
|
//}
|
||
|
|
||
|
//if (goname.StartsWith("uibgf"))
|
||
|
//{
|
||
|
// TipHasComponent<UICurBgFullScreen>(goname, tf, goinfo);
|
||
|
// return true;
|
||
|
//}
|
||
|
|
||
|
//if (goname.StartsWith("uibgs"))
|
||
|
//{
|
||
|
// TipHasComponent<UICurBgSmall>(goname, tf, goinfo);
|
||
|
// return true;
|
||
|
//}
|
||
|
|
||
|
//if (goname.StartsWith("uibgmt"))
|
||
|
//{
|
||
|
// TipHasComponent<UICurBgMiddle>(goname, tf, goinfo);
|
||
|
// return true;
|
||
|
//}
|
||
|
|
||
|
//if (goname.StartsWith("rri"))
|
||
|
//{
|
||
|
// TipHasComponent<UIRoleRawImage>(goname, tf, goinfo);
|
||
|
// return true;
|
||
|
|
||
|
//}
|
||
|
|
||
|
//if (goname.StartsWith("iil"))
|
||
|
//{
|
||
|
// TipHasComponent<UIItemIconList>(goname, tf, goinfo);
|
||
|
// return true;
|
||
|
//}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static void TipHasComponent<T>(string goname, Transform tf, GoInfo goinfo)
|
||
|
{
|
||
|
Type t = typeof(T);
|
||
|
if (tf.GetComponent<T>() == null)
|
||
|
{
|
||
|
Debug.LogErrorFormat("{0} 缺少 {1}", goname, t.Name);
|
||
|
}
|
||
|
goinfo.TypeName = t.Name;
|
||
|
goinfo.FullName = t.FullName;
|
||
|
}
|
||
|
|
||
|
[MenuItem("UI工具/生成UI预制体路径文件")]
|
||
|
public static void ExportUIPath()
|
||
|
{
|
||
|
Debug.Log("生成UI预制体路径 开始");
|
||
|
if (!Directory.Exists(UIPrefabRootPath))
|
||
|
Directory.CreateDirectory(UIPrefabRootPath);
|
||
|
|
||
|
//if (!Directory.Exists(UIMgr.UIPathConfigPath))
|
||
|
// Directory.CreateDirectory(UIMgr.UIPathConfigPath);
|
||
|
|
||
|
LoadScriptableObject();
|
||
|
|
||
|
Debug.Log(string.Format("<color=#{0}>{1}</color>", "00FF00", "生成UI预制体路径 完成"));
|
||
|
}
|
||
|
|
||
|
//private static void LoadScriptableObject()
|
||
|
//{
|
||
|
// var objs = EditorCommonAPI.LoadAllAssetsInAllPath<GameObject>(UIMgr.UIPrefabRootPath);
|
||
|
// if (objs == null)
|
||
|
// {
|
||
|
// Debug.LogError("未找到UI预制体, 根目录:" + UIMgr.UIPrefabRootPath);
|
||
|
// return;
|
||
|
// }
|
||
|
|
||
|
// string assetsFile = UIMgr.UIPathConfigFile;
|
||
|
// //如果文件存在, 直接移除
|
||
|
// AssetDatabase.DeleteAsset(assetsFile);
|
||
|
// AssetDatabase.Refresh();
|
||
|
|
||
|
|
||
|
// Debug.Log("UI预制体总数:" + objs.Count);
|
||
|
// // 找出所有 'UI' | 'Unit' 结尾的prefab
|
||
|
// List<GameObject> uis = new List<GameObject>();
|
||
|
// Dictionary<string, string> mUIToPathDic = new Dictionary<string, string>();
|
||
|
// foreach (var prefab in objs)
|
||
|
// {
|
||
|
|
||
|
// if (prefab.name.EndsWith("UI") || prefab.name.EndsWith("Unit"))
|
||
|
// {
|
||
|
// Debug.Log("" + prefab.name + ". path:" + PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab));
|
||
|
|
||
|
// string aPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab); // 绝对路径
|
||
|
// if (!aPath.EndsWith(".prefab"))
|
||
|
// {
|
||
|
// Debug.LogError("导出UI路径, 对象不是预制体. path:" + aPath);
|
||
|
// continue;
|
||
|
// }
|
||
|
|
||
|
// string rPath = aPath;
|
||
|
// uis.Add(prefab);
|
||
|
// mUIToPathDic.Add(prefab.name, rPath);
|
||
|
// }
|
||
|
// }
|
||
|
|
||
|
|
||
|
// UIMgrPath dataFile = AssetDatabase.LoadAssetAtPath<UIMgrPath>(assetsFile);
|
||
|
// if (dataFile != null)
|
||
|
// {// 有配置文件
|
||
|
// dataFile.mAllUIPath.Clear();
|
||
|
// foreach (var vPair in mUIToPathDic)
|
||
|
// {
|
||
|
// UIMgrPath.UIPath temp1 = new UIMgrPath.UIPath();
|
||
|
// temp1.mUIName = vPair.Key;
|
||
|
// temp1.mUIPath = vPair.Value;
|
||
|
// dataFile.mAllUIPath.Add(temp1);
|
||
|
// }
|
||
|
// }
|
||
|
// else
|
||
|
// {
|
||
|
// dataFile = CreateInstance<UIMgrPath>();// 创建配置文件
|
||
|
|
||
|
// dataFile.mAllUIPath.Clear();
|
||
|
// foreach (var vPair in mUIToPathDic)
|
||
|
// {
|
||
|
// UIMgrPath.UIPath temp1 = new UIMgrPath.UIPath();
|
||
|
// temp1.mUIName = vPair.Key;
|
||
|
// temp1.mUIPath = vPair.Value;
|
||
|
// dataFile.mAllUIPath.Add(temp1);
|
||
|
// }
|
||
|
|
||
|
// AssetDatabase.DeleteAsset(assetsFile);
|
||
|
// AssetDatabase.CreateAsset(dataFile, assetsFile);// 生成资源到指定路径
|
||
|
// }
|
||
|
|
||
|
// Debug.Log("更新了UI路径:assetsPath:" + assetsFile);
|
||
|
// AssetDatabase.SaveAssets();
|
||
|
// AssetDatabase.Refresh();
|
||
|
//}
|
||
|
|
||
|
|
||
|
private static void LoadScriptableObject()
|
||
|
{
|
||
|
var objs = EditorCommonAPI.LoadAllAssetsInAllPath<GameObject>(UIPrefabRootPath);
|
||
|
if (objs == null)
|
||
|
{
|
||
|
Debug.LogError("未找到UI预制体, 根目录:" + UIPrefabRootPath);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
string assetsFile = Application.dataPath.Replace("/Assets", "/") + UIPathConfigFile;
|
||
|
if (!File.Exists(assetsFile))
|
||
|
{
|
||
|
var sw = File.CreateText(assetsFile);
|
||
|
sw.Close();
|
||
|
}
|
||
|
if (!File.Exists(assetsFile))
|
||
|
{
|
||
|
Debug.LogError("LoadScriptableObject. !File.Exists(assetsFile). assetsFile:" + assetsFile);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Debug.Log("UI预制体总数:" + objs.Count);
|
||
|
// 找出所有 'UI' | 'Unit' 结尾的prefab
|
||
|
List<GameObject> uis = new List<GameObject>();
|
||
|
Dictionary<string, string> mUIToPathDic = new Dictionary<string, string>();
|
||
|
|
||
|
foreach (var prefab in objs)
|
||
|
{
|
||
|
if (prefab.name.EndsWith("UI")
|
||
|
|| prefab.name.EndsWith("Page")
|
||
|
|| prefab.name.EndsWith("Unit")
|
||
|
//|| prefab.name.EndsWith("Ctrl")
|
||
|
)
|
||
|
{
|
||
|
Debug.Log("" + prefab.name + ". path:" + PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab));
|
||
|
|
||
|
string aPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefab); // 绝对路径
|
||
|
if (!aPath.EndsWith(".prefab"))
|
||
|
{
|
||
|
Debug.LogError("导出UI路径, 对象不是预制体. path:" + aPath);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
string rPath = aPath;
|
||
|
uis.Add(prefab);
|
||
|
mUIToPathDic.Add(prefab.name, rPath);
|
||
|
}
|
||
|
}
|
||
|
string json = CaoCao.LitJson.JsonMapper.ToJson(mUIToPathDic);
|
||
|
|
||
|
File.WriteAllText(assetsFile, JObject.Parse(json).ToString());
|
||
|
Debug.Log("更新了UI路径:assetsPath:" + assetsFile);
|
||
|
}
|
||
|
|
||
|
}
|