| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 | 
							- using System.Collections.Generic;
 
- using System.Linq;
 
- using AssetBank.Editor.SchemaConverter.Data.Input;
 
- using AssetBank.Settings;
 
- using Newtonsoft.Json;
 
- using Newtonsoft.Json.Linq;
 
- using UnityEngine;
 
- namespace AssetBank.Editor.Tools
 
- {
 
-     public static class JsonDataTrimmer
 
-     {
 
-         public static string Process(string rawJsonText, ProjectExporterSettings settings)
 
-         {
 
-             var processedJson = ShortenBrokenPrefabGameObjects(rawJsonText);
 
-             
 
-             var allComponents = JArray.Parse(processedJson);
 
-             
 
-             // Pass 1: Build the definitive ruleset
 
-             var rules = settings.SafeComponents.ToDictionary(r => r.Component, r => r.ExposedFields.ToHashSet());
 
-             if (!settings.OverrideHardcodedDefaults)
 
-             {
 
-                 foreach (var hardcodedRule in settings.HardcodedComponents)
 
-                 {
 
-                     if (rules.TryGetValue(hardcodedRule.Component, out var userRules))
 
-                     {
 
-                         userRules.UnionWith(hardcodedRule.ExposedFields);
 
-                     }
 
-                     else
 
-                     {
 
-                         rules[hardcodedRule.Component] = hardcodedRule.ExposedFields.ToHashSet();
 
-                     }
 
-                 }
 
-             }
 
-             // Pass 2: Create a fully trimmed copy of every component
 
-             var trimmedComponentMap = new Dictionary<string, JObject>();
 
-             foreach (var component in allComponents.Children<JObject>())
 
-             {
 
-                 var anchorId = component["anchor_id"]?.ToString();
 
-                 if (string.IsNullOrEmpty(anchorId)) continue;
 
-                 var trimmedComponent = component.DeepClone() as JObject;
 
-                 var dataBlock = trimmedComponent["data"] as JObject;
 
-                 if (dataBlock == null || !dataBlock.HasValues)
 
-                 {
 
-                     trimmedComponentMap[anchorId] = trimmedComponent;
 
-                     continue;
 
-                 }
 
-                 var componentProperty = dataBlock.Properties().FirstOrDefault();
 
-                 if (componentProperty == null)
 
-                 {
 
-                     trimmedComponentMap[anchorId] = trimmedComponent;
 
-                     continue;
 
-                 }
 
-                 var componentName = componentProperty.Name;
 
-                 var componentJObject = componentProperty.Value as JObject;
 
-                 if (componentJObject == null)
 
-                 {
 
-                     trimmedComponentMap[anchorId] = trimmedComponent;
 
-                     continue;
 
-                 }
 
-                 if (rules.TryGetValue(componentName, out var exposedFields))
 
-                 {
 
-                     if (exposedFields.Contains("*"))
 
-                     {
 
-                         trimmedComponentMap[anchorId] = trimmedComponent;
 
-                         continue;
 
-                     }
 
-                     var propertiesToKeep = new HashSet<string>(exposedFields);
 
-                     var currentKeys = componentJObject.Properties().Select(p => p.Name).ToList();
 
-                     foreach (var key in currentKeys)
 
-                     {
 
-                         if (!propertiesToKeep.Contains(key))
 
-                         {
 
-                             componentJObject.Remove(key);
 
-                         }
 
-                     }
 
-                 }
 
-                 else
 
-                 {
 
-                     componentJObject.RemoveAll();
 
-                 }
 
-                 trimmedComponentMap[anchorId] = trimmedComponent;
 
-             }
 
-             
 
-             // Pass 3: Final Assembly
 
-             var finalOutput = new JArray();
 
-             var embeddedIds = new HashSet<string>();
 
-             // First, identify all components that will be embedded into GameObjects
 
-             foreach (var originalComponent in allComponents.Children<JObject>())
 
-             {
 
-                 if (originalComponent["data"]?["GameObject"]?["m_Component"] is JArray componentList)
 
-                 {
 
-                     foreach (var compRef in componentList.Children<JObject>())
 
-                     {
 
-                         if (compRef["component"]?["fileID"]?.ToString() is var fileID && !string.IsNullOrEmpty(fileID))
 
-                         {
 
-                             embeddedIds.Add(fileID);
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             // Now, build the final output, preserving order
 
-             foreach (var originalComponent in allComponents.Children<JObject>())
 
-             {
 
-                 var anchorId = originalComponent["anchor_id"]?.ToString();
 
-                 if (string.IsNullOrEmpty(anchorId) || embeddedIds.Contains(anchorId))
 
-                 {
 
-                     // If a component has no ID, or it's a child of a GameObject, skip it.
 
-                     // Children will be added via their parent GameObject.
 
-                     continue;
 
-                 }
 
-                 // Get the trimmed version of the current component
 
-                 if (!trimmedComponentMap.TryGetValue(anchorId, out var trimmedComponent))
 
-                 {
 
-                     // Should not happen, but as a safeguard, add the original.
 
-                     finalOutput.Add(originalComponent.DeepClone());
 
-                     continue;
 
-                 }
 
-                 // If it's a GameObject, embed its already-trimmed children
 
-                 if (originalComponent["data"]?["GameObject"] is JObject originalGameObjectData)
 
-                 {
 
-                     var trimmedGameObjectData = trimmedComponent["data"]["GameObject"] as JObject;
 
-                     var componentList = originalGameObjectData["m_Component"] as JArray;
 
-                     if (trimmedGameObjectData != null && componentList != null)
 
-                     {
 
-                         var newComponentList = new JArray();
 
-                         var gameObjectName = originalGameObjectData["m_Name"]?.ToString() ?? "Unnamed";
 
-                         foreach (var compRef in componentList.Children<JObject>())
 
-                         {
 
-                             var fileID = compRef["component"]?["fileID"]?.ToString();
 
-                             if (string.IsNullOrEmpty(fileID)) continue;
 
-                             if (trimmedComponentMap.TryGetValue(fileID, out var linkedComponent))
 
-                             {
 
-                                 var clonedData = linkedComponent["data"].DeepClone() as JObject;
 
-                                 (clonedData?.Properties().FirstOrDefault()?.Value as JObject)?.Remove("m_GameObject");
 
-                                 
 
-                                 // Re-inject the anchor_id to preserve the link information after trimming.
 
-                                 if (clonedData != null)
 
-                                 {
 
-                                     clonedData.AddFirst(new JProperty("anchor_id", fileID));
 
-                                 }
 
-                                 
 
-                                 newComponentList.Add(clonedData);
 
-                             }
 
-                             else
 
-                             {
 
-                                 Debug.LogWarning($"JsonDataTrimmer: Could not find component with anchor_id '{fileID}' referenced by GameObject '{gameObjectName}'.");
 
-                             }
 
-                         }
 
-                         trimmedGameObjectData["m_Component"] = newComponentList;
 
-                     }
 
-                 }
 
-                 
 
-                 finalOutput.Add(trimmedComponent);
 
-             }
 
-             return finalOutput.ToString(Newtonsoft.Json.Formatting.None);
 
-         }
 
-         private static string ShortenBrokenPrefabGameObjects(string data)
 
-         {
 
-             var nodes = JsonConvert.DeserializeObject<List<OriginalNode>>(data);
 
-             
 
-             if (nodes == null)
 
-             {
 
-                 return data;
 
-             }
 
-             
 
-             const string gameObjectTypeId = "1";
 
-             const string prefabTypeId = "1001";
 
-             const string transformTypeId = "4";
 
-             var allGameObjects = nodes.Where(n => n.type_id == gameObjectTypeId).ToList();
 
-             var allTransforms = nodes.Where(n => n.type_id == transformTypeId).ToList();
 
-             var allPrefabs = nodes.Where(n => n.type_id == prefabTypeId).ToList();
 
-             var restOfComponents = nodes.Where(n => n.type_id != gameObjectTypeId && n.type_id != prefabTypeId && n.type_id != transformTypeId).ToList();
 
-             
 
-             foreach (var gameObject in allGameObjects)
 
-             {
 
-                 var nodeIndex = nodes.IndexOf(gameObject);
 
-                 var prefabInstanceId = gameObject.data?["GameObject"]?["m_PrefabInstance"]?["fileID"]?.ToString();
 
-                 if (string.IsNullOrEmpty(prefabInstanceId) || prefabInstanceId == "0") continue;
 
-                 var prefab = allPrefabs.FirstOrDefault(p => p.anchor_id == prefabInstanceId);
 
-                 if (prefab == null)
 
-                 {
 
-                     Debug.LogWarning($"JsonDataTrimmer: Could not find prefab with anchor_id '{prefabInstanceId}' referenced by GameObject '{gameObject.data?["GameObject"]?["m_Name"]}'.");
 
-                     continue;
 
-                 }
 
-                 var prefabGuid = prefab.data?["PrefabInstance"]?["m_SourcePrefab"]?["guid"]?.ToString();
 
-                 if (string.IsNullOrEmpty(prefabGuid))
 
-                 {
 
-                     Debug.LogWarning($"JsonDataTrimmer: Could not find GUID for prefab with anchor_id '{prefabInstanceId}' referenced by GameObject '{gameObject.data?["GameObject"]?["m_Name"]}'.");
 
-                     continue;
 
-                 }
 
-                 var relatedTransform = allTransforms.FirstOrDefault(t => t.data?["Transform"]?["m_PrefabInstance"]?["fileID"]?.ToString() == prefabInstanceId);
 
-                 if (relatedTransform == null)
 
-                 {
 
-                     Debug.LogWarning($"JsonDataTrimmer: Could not find Transform with anchor_id '{prefabInstanceId}' referenced by GameObject '{gameObject.data?["GameObject"]?["m_Name"]}'.");
 
-                     continue;
 
-                 }
 
-                 var relatedComponents = restOfComponents.Where(c => c.data?.SelectToken("*.m_GameObject.fileID")?.ToString() == gameObject.anchor_id).ToList();
 
-                 
 
-                 var newNode = new OriginalNode
 
-                 {
 
-                     type_id = gameObject.type_id,
 
-                     anchor_id = gameObject.anchor_id,
 
-                     data = gameObject.data
 
-                 };
 
-                 var jArray = new JArray();
 
-                 foreach (var component in relatedComponents)
 
-                 {
 
-                     jArray.Add(JObject.FromObject(new
 
-                     {
 
-                         component = new
 
-                         {
 
-                             fileID = component.anchor_id
 
-                         }
 
-                     }));
 
-                 }
 
-                 jArray.Add(JObject.FromObject(new
 
-                 {
 
-                     component = new
 
-                     {
 
-                         fileID = relatedTransform.anchor_id
 
-                     }
 
-                 }));
 
-                 newNode.data["GameObject"]!["m_Component"] = jArray;
 
-                 nodes[nodeIndex] = newNode;
 
-             }
 
-             return JsonConvert.SerializeObject(nodes, Formatting.None);
 
-         }
 
-     }
 
- }
 
 
  |