/******************************************************************** 文件: FrameCodeGenerate.cs 作者: 梦语 邮箱: 1982614048@qq.com 创建时间: 2024/03/29 17:28:19 最后修改: 梦语 最后修改时间: 2024/04/04 16:34:30 功能: 生成界面基类 *********************************************************************/ using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using UnityEditor; using UnityEngine; using System.Linq; namespace Ether { public class FrameCodeGenerate { public enum ComponentType { Image, Go, Btn, BtnEx, Text, SRContent, ScrollRect, Animator, Trans, } private static Dictionary relationDic = new Dictionary() { { ComponentType.Image, "Image" }, { ComponentType.Go, "GameObject" }, { ComponentType.Trans, "Transform" }, { ComponentType.Btn, "Button" }, { ComponentType.BtnEx, "ButtonEx" }, { ComponentType.Text, "TextMeshProUGUI" }, { ComponentType.SRContent, "ScrollContent" }, { ComponentType.ScrollRect, "ScrollRect" }, { ComponentType.Animator, "Animator" }, }; [MenuItem("Assets/生成FrameBase(=-=)", false, 19)] private static void CodeGenerate() { GameObject selectedPrefab = Selection.activeGameObject; if (selectedPrefab != null && PrefabUtility.IsPartOfAnyPrefab(selectedPrefab)) { Transform[] childs = selectedPrefab.GetComponentsInChildren(true); Dictionary)> componentDic = new Dictionary)>(); foreach (Transform child in childs) { if (child.name == selectedPrefab.name) { continue; } (string, List) childComponent = CheckClildName(child); string childPath = GetChildPath(child); if (!componentDic.ContainsKey(childPath)) { componentDic.Add(childPath, childComponent); } } GenerateFrameBase(selectedPrefab, componentDic); } else { Debug.LogError("当前没有选中预制体!"); } } [MenuItem("Assets/生成FrameBase(=-=)", true, 19)] public static bool CodeGenerateShow() { GameObject selectedPrefab = Selection.activeGameObject; if (selectedPrefab != null && PrefabUtility.IsPartOfAnyPrefab(selectedPrefab)) { return true; } else { return false; } } /// /// 检查子物体的名字,获取对应的组件 /// /// /// private static (string, List) CheckClildName(Transform child) { string input = child.name; string pattern = @"<(.*?)>"; List childTypeList = new List(); string childName = input; MatchCollection matches = Regex.Matches(input, pattern); foreach (Match match in matches) { childName = childName.Replace(match.Groups[0].Value, ""); string content = match.Groups[1].Value; if (Enum.TryParse(content, out ComponentType parsedEnum)) { if (Enum.IsDefined(typeof(ComponentType), parsedEnum)) { childTypeList.Add(parsedEnum); } } } return (childName, childTypeList); } /// /// 获取子物体的路径 /// /// /// private static string GetChildPath(Transform child) { string path = child.name; Transform parent = child.parent; while (parent != null) { path = parent.name + "/" + path; parent = parent.parent; } //去除本身的路径 int slashIndex = path.IndexOf("/"); if (slashIndex >= 0) { path = path.Substring(slashIndex + 1); } return path; } private static string templeteFileName = Application.dataPath + $"/Ether/Editor/Frames/FrameTemplete.txt"; /// /// 生成FrameBase /// /// private static void GenerateFrameBase(GameObject selectedPrefab, Dictionary)> componentDic) { string selectPath = AssetDatabase.GetAssetPath(selectedPrefab); string framePart = "Prefabs"; int selectIndex = selectPath.IndexOf(framePart); string framePrefabPath = selectPath.Substring(selectIndex).Replace(".prefab", ""); Debug.Log($"selectPath:{selectPath}"); string frameTemplete = FileTools.ReadFile(templeteFileName); Debug.Log(frameTemplete); (string, string) generateComponentCode = GenerateComponentCodeStr(componentDic); string pattern = @"\$(.*?)\$"; MatchCollection matches = Regex.Matches(frameTemplete, pattern); foreach (Match match in matches) { string property = match.Groups[0].Value; //带$的原字符串 string content = match.Groups[1].Value; //仅两个$中的内容 string replaceStr = ""; switch (content) { case "FrameBaseName": replaceStr = $"{selectedPrefab.name}Base"; break; case "PrefabPath": replaceStr = framePrefabPath; break; case "PropertyList": replaceStr = generateComponentCode.Item1; break; case "PropertyInitList": replaceStr = generateComponentCode.Item2; break; default: break; } //Debug.Log(content); frameTemplete = frameTemplete.Replace(property, replaceStr); } string basePath = Application.dataPath + $"/Scripts/AutoGenerated/FrameBase/{selectedPrefab.name}Base.cs"; if (File.Exists(basePath)) File.Delete(basePath); FileTools.WriteFile(basePath, frameTemplete); AssetDatabase.Refresh(); return; } private static (string, string) GenerateComponentCodeStr(Dictionary)> componentDic) { string define = ""; string code = ""; string name = ""; foreach (var component in componentDic) { name = component.Value.Item1; foreach (var type in component.Value.Item2) { string tempType; if (relationDic.ContainsKey(type)) { tempType = relationDic[type]; } else { tempType = type.ToString(); } define += $"protected {tempType} _{type}{name};\n\t\t"; code += GetCodeByComponentType(type, tempType, name, component.Key); } } return (define, code); } private static string GetCodeByComponentType(ComponentType type, string componentName, string name, string path) { string code = ""; switch (type) { case ComponentType.Go: code = $"_{type}{name} = GetChild(\"{path}\").gameObject;\n\t\t\t"; break; case ComponentType.Image: case ComponentType.Btn: case ComponentType.BtnEx: case ComponentType.Text: default: code = $"_{type}{name} = GetComponent<{componentName}>(\"{path}\");\n\t\t\t"; break; } return code; } } }