127 lines
4.9 KiB
C#
127 lines
4.9 KiB
C#
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Text;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
namespace PuertsConfigs.Editor
|
||
{
|
||
public class PrefabStructureGenerator : EditorWindow
|
||
{
|
||
[MenuItem("Tools/Generate Prefab Structure Definition")]
|
||
public static void GeneratePrefabStructureDefinition()
|
||
{
|
||
StringBuilder tsDefinition = new StringBuilder();
|
||
tsDefinition.AppendLine("// Auto-generated by PrefabStructureGenerator");
|
||
tsDefinition.AppendLine("declare type UnityPrefabs = {");
|
||
|
||
// 查找所有Resources文件夹
|
||
string[] resourcesDirs = Directory.GetDirectories(Application.dataPath, "Resources", SearchOption.AllDirectories);
|
||
|
||
Dictionary<string, Dictionary<string, List<string>>> allPrefabs = new Dictionary<string, Dictionary<string, List<string>>>();
|
||
|
||
foreach (string resourcesDir in resourcesDirs)
|
||
{
|
||
// 获取Resources文件夹下的所有Prefab
|
||
string relativePath = resourcesDir.Replace(Application.dataPath, "Assets");
|
||
string[] prefabPaths = Directory.GetFiles(relativePath, "*.prefab", SearchOption.AllDirectories);
|
||
|
||
foreach (string prefabPath in prefabPaths)
|
||
{
|
||
// 获取Prefab的相对Resources路径(不带扩展名)
|
||
string resourcesRelativePath = prefabPath
|
||
.Replace(relativePath + Path.DirectorySeparatorChar, "")
|
||
.Replace(".prefab", "");
|
||
|
||
// 加载Prefab
|
||
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
||
if (prefab == null) continue;
|
||
|
||
// 记录Prefab结构
|
||
Dictionary<string, List<string>> prefabStructure = new Dictionary<string, List<string>>();
|
||
RecordGameObjectComponents(prefab, "", prefabStructure);
|
||
|
||
allPrefabs[resourcesRelativePath] = prefabStructure;
|
||
}
|
||
}
|
||
|
||
// 生成TypeScript定义
|
||
foreach (var kvp in allPrefabs)
|
||
{
|
||
tsDefinition.AppendLine($" \"{kvp.Key}\": {{");
|
||
|
||
foreach (var componentKvp in kvp.Value)
|
||
{
|
||
string path = componentKvp.Key;
|
||
List<string> components = componentKvp.Value;
|
||
|
||
if (string.IsNullOrEmpty(path))
|
||
{
|
||
tsDefinition.Append(" \"\": ");
|
||
}
|
||
else
|
||
{
|
||
tsDefinition.Append($" \"{path}\": ");
|
||
}
|
||
|
||
tsDefinition.Append("[");
|
||
for (int i = 0; i < components.Count; i++)
|
||
{
|
||
if (i > 0) tsDefinition.Append(", ");
|
||
tsDefinition.Append(components[i]);
|
||
}
|
||
tsDefinition.AppendLine("],");
|
||
}
|
||
|
||
tsDefinition.AppendLine(" },");
|
||
}
|
||
|
||
tsDefinition.AppendLine("}");
|
||
|
||
// 确保输出目录存在
|
||
string outputDir = Path.Combine(Application.dataPath, "Gen", "Prefabs");
|
||
if (!Directory.Exists(outputDir))
|
||
{
|
||
Directory.CreateDirectory(outputDir);
|
||
}
|
||
|
||
// 写入文件
|
||
string outputPath = Path.Combine(outputDir, "index.d.ts");
|
||
File.WriteAllText(outputPath, tsDefinition.ToString());
|
||
|
||
AssetDatabase.Refresh();
|
||
Debug.Log($"Prefab structure definition generated at: {outputPath}");
|
||
}
|
||
|
||
private static void RecordGameObjectComponents(GameObject go, string currentPath, Dictionary<string, List<string>> structure)
|
||
{
|
||
// 记录当前GameObject的组件
|
||
Component[] components = go.GetComponents<Component>();
|
||
List<string> componentTypes = new List<string>();
|
||
|
||
foreach (Component component in components)
|
||
{
|
||
if (component == null) continue;
|
||
string typeName = $"CS.{component.GetType().FullName}";
|
||
componentTypes.Add(typeName);
|
||
}
|
||
|
||
if (componentTypes.Count > 0)
|
||
{
|
||
structure[currentPath] = componentTypes;
|
||
}
|
||
|
||
// 递归处理子对象
|
||
for (int i = 0; i < go.transform.childCount; i++)
|
||
{
|
||
Transform child = go.transform.GetChild(i);
|
||
string childPath = string.IsNullOrEmpty(currentPath)
|
||
? child.name
|
||
: $"{currentPath}/{child.name}";
|
||
|
||
RecordGameObjectComponents(child.gameObject, childPath, structure);
|
||
}
|
||
}
|
||
}
|
||
}
|