unity-puerts-template/unityscripts/Editor/PrefabStructureGenerator.cs

127 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}
}