diff --git a/unityscripts/Editor/PrefabStructureGenerator.cs b/unityscripts/Editor/PrefabStructureGenerator.cs new file mode 100644 index 0000000..81e20cf --- /dev/null +++ b/unityscripts/Editor/PrefabStructureGenerator.cs @@ -0,0 +1,126 @@ +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>> allPrefabs = new Dictionary>>(); + + 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(prefabPath); + if (prefab == null) continue; + + // 记录Prefab结构 + Dictionary> prefabStructure = new Dictionary>(); + 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 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> structure) + { + // 记录当前GameObject的组件 + Component[] components = go.GetComponents(); + List componentTypes = new List(); + + 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); + } + } + } +}