IndieGame/client/Assets/Ether/Editor/Frames/FrameCodeGenerate.cs

269 lines
8.8 KiB
C#
Raw Normal View History

2024-10-11 10:12:15 +08:00
/********************************************************************
: 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<ComponentType, string> relationDic = new Dictionary<ComponentType, string>()
{
{ 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<Transform>(true);
Dictionary<string, (string, List<ComponentType>)> componentDic = new Dictionary<string, (string, List<ComponentType>)>();
foreach (Transform child in childs)
{
if (child.name == selectedPrefab.name)
{
continue;
}
(string, List<ComponentType>) 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;
}
}
/// <summary>
/// 检查子物体的名字,获取对应的组件
/// </summary>
/// <param name="child"></param>
/// <returns></returns>
private static (string, List<ComponentType>) CheckClildName(Transform child)
{
string input = child.name;
string pattern = @"<(.*?)>";
List<ComponentType> childTypeList = new List<ComponentType>();
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);
}
/// <summary>
/// 获取子物体的路径
/// </summary>
/// <param name="child"></param>
/// <returns></returns>
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";
/// <summary>
/// 生成FrameBase
/// </summary>
/// <param name="componentDic"></param>
private static void GenerateFrameBase(GameObject selectedPrefab, Dictionary<string, (string, List<ComponentType>)> 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<string, (string, List<ComponentType>)> 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;
}
}
}