Chocolade19721309

Untitled

May 17th, 2024
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.32 KB | None | 0 0
  1. using UnityEditor;
  2. using UnityEngine;
  3. using UnityEngine.SceneManagement;
  4. using System.IO;
  5. using System.Collections.Generic;
  6. using System.Text;
  7. using Newtonsoft.Json;
  8. using System.Linq;
  9.  
  10. public class HierarchyTextLogger : EditorWindow
  11. {
  12. private bool logTransform = true;
  13. private bool logRigidbody = true;
  14. private bool logAsJson = true;
  15. private bool includeAllScripts = false;
  16. private bool includeOnlyEditorScripts = false;
  17. private bool includeAllProperties = false;
  18. private string customOutputPath = "Assets/HierarchyLog";
  19. private bool includeSpecificComponents = false;
  20. private string specificComponents = "";
  21. private bool logSpecificLayers = false;
  22. private string specificLayers = "";
  23. private bool logSpecificTags = false;
  24. private string specificTags = "";
  25.  
  26. [MenuItem("Tools/Hierarchy Text Logger")]
  27. public static void ShowWindow()
  28. {
  29. GetWindow<HierarchyTextLogger>("Hierarchy Logger");
  30. }
  31.  
  32. void OnGUI()
  33. {
  34. GUILayout.Label("Select Components to Log:", EditorStyles.boldLabel);
  35. logTransform = EditorGUILayout.Toggle("Log Transform", logTransform);
  36. logRigidbody = EditorGUILayout.Toggle("Log Rigidbody", logRigidbody);
  37. logAsJson = EditorGUILayout.Toggle("Output as JSON", logAsJson);
  38. includeAllScripts = EditorGUILayout.Toggle("Include All Scripts", includeAllScripts);
  39. if (includeAllScripts)
  40. includeOnlyEditorScripts = false;
  41. includeOnlyEditorScripts = EditorGUILayout.Toggle("Include Only Editor Scripts", includeOnlyEditorScripts);
  42. if (includeOnlyEditorScripts)
  43. includeAllScripts = false;
  44. includeAllProperties = EditorGUILayout.Toggle("Include All Properties", includeAllProperties);
  45.  
  46. GUILayout.Space(10);
  47.  
  48. customOutputPath = EditorGUILayout.TextField("Output Path", customOutputPath);
  49.  
  50. includeSpecificComponents = EditorGUILayout.Toggle("Log Specific Components", includeSpecificComponents);
  51. if (includeSpecificComponents)
  52. {
  53. specificComponents = EditorGUILayout.TextField("Component Types (comma separated)", specificComponents);
  54. }
  55.  
  56. logSpecificLayers = EditorGUILayout.Toggle("Log Specific Layers", logSpecificLayers);
  57. if (logSpecificLayers)
  58. {
  59. specificLayers = EditorGUILayout.TextField("Layer Names (comma separated)", specificLayers);
  60. }
  61.  
  62. logSpecificTags = EditorGUILayout.Toggle("Log Specific Tags", logSpecificTags);
  63. if (logSpecificTags)
  64. {
  65. specificTags = EditorGUILayout.TextField("Tag Names (comma separated)", specificTags);
  66. }
  67.  
  68. GUILayout.Space(10);
  69.  
  70. if (GUILayout.Button("Log Hierarchy"))
  71. {
  72. LogHierarchy();
  73. }
  74.  
  75. GUILayout.Space(10);
  76.  
  77. if (GUILayout.Button("Import Hierarchy from JSON"))
  78. {
  79. ImportHierarchyFromJson();
  80. }
  81. }
  82.  
  83. private void LogHierarchy()
  84. {
  85. var allObjects = new List<object>();
  86. StringBuilder builder = new StringBuilder();
  87.  
  88. foreach (GameObject obj in SceneManager.GetActiveScene().GetRootGameObjects())
  89. {
  90. var objectData = LogObjectHierarchy(obj, builder, 0);
  91. if (logAsJson)
  92. allObjects.Add(objectData);
  93. else
  94. builder.AppendLine("");
  95. }
  96.  
  97. string filePath = logAsJson ? $"{customOutputPath}.json" : $"{customOutputPath}.txt";
  98. File.WriteAllText(filePath, logAsJson ? Newtonsoft.Json.JsonConvert.SerializeObject(allObjects, Newtonsoft.Json.Formatting.Indented) : builder.ToString());
  99.  
  100. AssetDatabase.Refresh();
  101. }
  102.  
  103. private Dictionary<string, object> LogObjectHierarchy(GameObject obj, StringBuilder builder, int depth)
  104. {
  105. Dictionary<string, object> objectData = new Dictionary<string, object>();
  106. string indent = new string(' ', depth * 2);
  107.  
  108. if (logSpecificLayers && !specificLayers.Split(',').Select(s => s.Trim()).Contains(LayerMask.LayerToName(obj.layer)))
  109. return null;
  110.  
  111. if (logSpecificTags && !specificTags.Split(',').Select(s => s.Trim()).Contains(obj.tag))
  112. return null;
  113.  
  114. builder.AppendLine($"{indent}GameObject: {obj.name}");
  115. objectData["Name"] = obj.name;
  116. objectData["Components"] = new List<object>();
  117.  
  118. foreach (Component component in obj.GetComponents<Component>())
  119. {
  120. if (includeSpecificComponents && !specificComponents.Split(',').Select(s => s.Trim()).Contains(component.GetType().Name))
  121. continue;
  122.  
  123. if (includeAllScripts && component is MonoBehaviour)
  124. {
  125. MonoBehaviour mono = component as MonoBehaviour;
  126. var script = MonoScript.FromMonoBehaviour(mono);
  127. var path = AssetDatabase.GetAssetPath(script);
  128. if (!string.IsNullOrEmpty(path))
  129. {
  130. string scriptContent = File.ReadAllText(path);
  131. Dictionary<string, string> scriptData = new Dictionary<string, string>
  132. {
  133. ["Name"] = mono.GetType().Name,
  134. ["Content"] = scriptContent
  135. };
  136. ((List<object>)objectData["Components"]).Add(scriptData);
  137. }
  138. }
  139.  
  140. SerializedObject serializedObject = new SerializedObject(component);
  141. SerializedProperty prop = serializedObject.GetIterator();
  142. if (prop.NextVisible(true))
  143. {
  144. var componentData = new Dictionary<string, string>
  145. {
  146. ["Type"] = component.GetType().AssemblyQualifiedName
  147. };
  148. do
  149. {
  150. if (!includeAllProperties && !((component is Transform && logTransform) || (component is Rigidbody && logRigidbody)))
  151. continue;
  152.  
  153. string value = GetPropertyValue(prop);
  154. componentData[prop.displayName] = value;
  155. builder.AppendLine($"{indent} {prop.displayName}: {value}");
  156. } while (prop.NextVisible(false));
  157. ((List<object>)objectData["Components"]).Add(componentData);
  158. }
  159. }
  160.  
  161. objectData["Children"] = new List<object>();
  162. foreach (Transform child in obj.transform)
  163. {
  164. var childData = LogObjectHierarchy(child.gameObject, builder, depth + 1);
  165. if (childData != null)
  166. ((List<object>)objectData["Children"]).Add(childData);
  167. }
  168.  
  169. return objectData;
  170. }
  171.  
  172. private string GetPropertyValue(SerializedProperty prop)
  173. {
  174. try
  175. {
  176. switch (prop.propertyType)
  177. {
  178. case SerializedPropertyType.LayerMask:
  179. if (prop.intValue < 0 || prop.intValue >= UnityEngine.LayerMask.NameToLayer("UserLayerB") + 1)
  180. return "Invalid layer";
  181. return LayerMask.LayerToName(prop.intValue);
  182. case SerializedPropertyType.Integer:
  183. return prop.intValue.ToString();
  184. case SerializedPropertyType.Boolean:
  185. return prop.boolValue.ToString();
  186. case SerializedPropertyType.Float:
  187. return prop.floatValue.ToString("R");
  188. case SerializedPropertyType.String:
  189. return prop.stringValue;
  190. case SerializedPropertyType.Color:
  191. return prop.colorValue.ToString();
  192. case SerializedPropertyType.ObjectReference:
  193. return prop.objectReferenceValue != null ? prop.objectReferenceValue.name : "None";
  194. case SerializedPropertyType.Enum:
  195. return prop.enumNames[prop.enumValueIndex];
  196. case SerializedPropertyType.Vector2:
  197. return prop.vector2Value.ToString();
  198. case SerializedPropertyType.Vector3:
  199. return prop.vector3Value.ToString();
  200. case SerializedPropertyType.Vector4:
  201. return prop.vector4Value.ToString();
  202. case SerializedPropertyType.Rect:
  203. return prop.rectValue.ToString();
  204. case SerializedPropertyType.ArraySize:
  205. return prop.arraySize.ToString();
  206. case SerializedPropertyType.AnimationCurve:
  207. return prop.animationCurveValue != null ? prop.animationCurveValue.ToString() : "None";
  208. case SerializedPropertyType.Bounds:
  209. return prop.boundsValue.ToString();
  210. case SerializedPropertyType.Gradient:
  211. return "<Gradient unsupported>";
  212. case SerializedPropertyType.Quaternion:
  213. return prop.quaternionValue.ToString();
  214. case SerializedPropertyType.ExposedReference:
  215. return prop.exposedReferenceValue != null ? prop.exposedReferenceValue.ToString() : "None";
  216. case SerializedPropertyType.FixedBufferSize:
  217. return prop.fixedBufferSize.ToString();
  218. case SerializedPropertyType.Vector2Int:
  219. return prop.vector2IntValue.ToString();
  220. case SerializedPropertyType.Vector3Int:
  221. return prop.vector3IntValue.ToString();
  222. case SerializedPropertyType.RectInt:
  223. return prop.rectIntValue.ToString();
  224. case SerializedPropertyType.BoundsInt:
  225. return prop.boundsIntValue.ToString();
  226. default:
  227. return "<Unsupported Type>";
  228. }
  229. }
  230. catch (System.Exception ex)
  231. {
  232. return $"Error: {ex.Message}";
  233. }
  234. }
  235.  
  236. void OnEnable()
  237. {
  238. includeAllScripts = EditorPrefs.GetBool("IncludeAllScripts", false);
  239. includeOnlyEditorScripts = EditorPrefs.GetBool("IncludeOnlyEditorScripts", false);
  240. includeAllProperties = EditorPrefs.GetBool("IncludeAllProperties", false);
  241. customOutputPath = EditorPrefs.GetString("CustomOutputPath", "Assets/HierarchyLog");
  242. includeSpecificComponents = EditorPrefs.GetBool("IncludeSpecificComponents", false);
  243. specificComponents = EditorPrefs.GetString("SpecificComponents", "");
  244. logSpecificLayers = EditorPrefs.GetBool("LogSpecificLayers", false);
  245. specificLayers = EditorPrefs.GetString("SpecificLayers", "");
  246. logSpecificTags = EditorPrefs.GetBool("LogSpecificTags", false);
  247. specificTags = EditorPrefs.GetString("SpecificTags", "");
  248. }
  249.  
  250. void OnDisable()
  251. {
  252. EditorPrefs.SetBool("IncludeAllScripts", includeAllScripts);
  253. EditorPrefs.SetBool("IncludeOnlyEditorScripts", includeOnlyEditorScripts);
  254. EditorPrefs.SetBool("IncludeAllProperties", includeAllProperties);
  255. EditorPrefs.SetString("CustomOutputPath", customOutputPath);
  256. EditorPrefs.SetBool("IncludeSpecificComponents", includeSpecificComponents);
  257. EditorPrefs.SetString("SpecificComponents", specificComponents);
  258. EditorPrefs.SetBool("LogSpecificLayers", logSpecificLayers);
  259. EditorPrefs.SetString("SpecificLayers", specificLayers);
  260. EditorPrefs.SetBool("LogSpecificTags", logSpecificTags);
  261. EditorPrefs.SetString("SpecificTags", specificTags);
  262. }
  263.  
  264. private void ImportHierarchyFromJson()
  265. {
  266. string importPath = $"{customOutputPath}.json";
  267.  
  268. if (!File.Exists(importPath))
  269. {
  270. Debug.LogError("JSON file not found at the specified path.");
  271. return;
  272. }
  273.  
  274. string jsonContent = File.ReadAllText(importPath);
  275. var rootObjectData = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jsonContent);
  276.  
  277. if (rootObjectData != null)
  278. {
  279. foreach (var objectData in rootObjectData)
  280. {
  281. CreateGameObjectFromJson(objectData, null);
  282. }
  283. }
  284.  
  285. AssetDatabase.Refresh();
  286. }
  287.  
  288. private void CreateGameObjectFromJson(Dictionary<string, object> objectData, Transform parent)
  289. {
  290. if (!objectData.ContainsKey("Name"))
  291. {
  292. Debug.LogError("Object data does not contain 'Name' key.");
  293. return;
  294. }
  295.  
  296. string name = objectData["Name"].ToString();
  297. GameObject newObject = new GameObject(name);
  298. Debug.Log($"Created GameObject: {name}");
  299.  
  300. if (parent != null)
  301. {
  302. newObject.transform.SetParent(parent);
  303. }
  304.  
  305. if (objectData.ContainsKey("Components"))
  306. {
  307. var components = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(objectData["Components"].ToString());
  308. foreach (var componentData in components)
  309. {
  310. if (componentData != null && componentData.ContainsKey("Type"))
  311. {
  312. string componentName = componentData["Type"].ToString();
  313. Component component = newObject.AddComponent(System.Type.GetType(componentName));
  314. Debug.Log($"Added Component: {componentName} to {name}");
  315.  
  316. if (component != null)
  317. {
  318. SerializedObject serializedObject = new SerializedObject(component);
  319. foreach (var prop in componentData)
  320. {
  321. if (prop.Key == "Type")
  322. continue;
  323.  
  324. SerializedProperty serializedProperty = serializedObject.FindProperty(prop.Key);
  325. if (serializedProperty != null)
  326. {
  327. SetPropertyValue(serializedProperty, prop.Value.ToString());
  328. }
  329. else
  330. {
  331. Debug.LogWarning($"Property '{prop.Key}' not found in component '{componentName}'");
  332. }
  333. }
  334. serializedObject.ApplyModifiedProperties();
  335. }
  336. else
  337. {
  338. Debug.LogError($"Failed to add component '{componentName}' to GameObject '{name}'");
  339. }
  340. }
  341. }
  342. }
  343. else
  344. {
  345. Debug.LogError($"Object '{name}' does not contain 'Components' key or 'Components' is not a list.");
  346. }
  347.  
  348. if (objectData.ContainsKey("Children"))
  349. {
  350. var children = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(objectData["Children"].ToString());
  351. foreach (var childData in children)
  352. {
  353. if (childData != null)
  354. {
  355. CreateGameObjectFromJson(childData, newObject.transform);
  356. }
  357. }
  358. }
  359. }
  360.  
  361. private void SetPropertyValue(SerializedProperty prop, string value)
  362. {
  363. try
  364. {
  365. switch (prop.propertyType)
  366. {
  367. case SerializedPropertyType.Integer:
  368. prop.intValue = int.Parse(value);
  369. break;
  370. case SerializedPropertyType.Boolean:
  371. prop.boolValue = bool.Parse(value);
  372. break;
  373. case SerializedPropertyType.Float:
  374. prop.floatValue = float.Parse(value);
  375. break;
  376. case SerializedPropertyType.String:
  377. prop.stringValue = value;
  378. break;
  379. case SerializedPropertyType.Color:
  380. prop.colorValue = ColorUtility.TryParseHtmlString(value, out Color color) ? color : Color.white;
  381. break;
  382. case SerializedPropertyType.ObjectReference:
  383. // This is a simplification. Ideally, you'd resolve the reference properly.
  384. prop.objectReferenceValue = null;
  385. break;
  386. case SerializedPropertyType.Enum:
  387. prop.enumValueIndex = prop.enumNames.ToList().IndexOf(value);
  388. break;
  389. case SerializedPropertyType.Vector2:
  390. prop.vector2Value = JsonConvert.DeserializeObject<Vector2>(value);
  391. break;
  392. case SerializedPropertyType.Vector3:
  393. prop.vector3Value = JsonConvert.DeserializeObject<Vector3>(value);
  394. break;
  395. case SerializedPropertyType.Vector4:
  396. prop.vector4Value = JsonConvert.DeserializeObject<Vector4>(value);
  397. break;
  398. case SerializedPropertyType.Rect:
  399. prop.rectValue = JsonConvert.DeserializeObject<Rect>(value);
  400. break;
  401. case SerializedPropertyType.Bounds:
  402. prop.boundsValue = JsonConvert.DeserializeObject<Bounds>(value);
  403. break;
  404. case SerializedPropertyType.Quaternion:
  405. prop.quaternionValue = JsonConvert.DeserializeObject<Quaternion>(value);
  406. break;
  407. case SerializedPropertyType.Vector2Int:
  408. prop.vector2IntValue = JsonConvert.DeserializeObject<Vector2Int>(value);
  409. break;
  410. case SerializedPropertyType.Vector3Int:
  411. prop.vector3IntValue = JsonConvert.DeserializeObject<Vector3Int>(value);
  412. break;
  413. case SerializedPropertyType.RectInt:
  414. prop.rectIntValue = JsonConvert.DeserializeObject<RectInt>(value);
  415. break;
  416. case SerializedPropertyType.BoundsInt:
  417. prop.boundsIntValue = JsonConvert.DeserializeObject<BoundsInt>(value);
  418. break;
  419. default:
  420. Debug.LogWarning($"Unsupported property type: {prop.propertyType}");
  421. break;
  422. }
  423. }
  424. catch (System.Exception ex)
  425. {
  426. Debug.LogError($"Failed to set property value: {ex.Message}");
  427. }
  428. }
  429. }
Advertisement
Add Comment
Please, Sign In to add comment