public static void BuildAssetList(Dictionary <Object, AssetItem> tempDic, bool displayAll, bool displayOriginalName, out string productName) { StatusStripUpdate("Building asset list..."); string OutPutPath = "OutputResult"; if (Directory.Exists(OutPutPath) == false) { Directory.CreateDirectory(OutPutPath); } else { Directory.Delete(OutPutPath, true); Directory.CreateDirectory(OutPutPath); } productName = string.Empty; var assetsNameHash = new HashSet <string>(); var progressCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count); int j = 0; Progress.Reset(); var allAssetsInfoDic = new Dictionary <string, List <string> >(); foreach (var assetsFile in assetsManager.assetsFileList) { var assetsInfoList = new List <string>(); var meshTmpInfoList = new List <MeshTmpInfo>(); var fbxInfoDic = new Dictionary <Object, Object>(); var tempExportableAssets = new List <AssetItem>(); AssetBundle ab = null; foreach (var asset in assetsFile.Objects.Values) { var assetItem = new AssetItem(asset); tempDic.Add(asset, assetItem); assetItem.UniqueID = " #" + j; var exportable = false; switch (asset) { case GameObject m_GameObject: assetItem.Text = m_GameObject.m_Name; if (m_GameObject.m_MeshFilter != null) { if (m_GameObject.m_MeshFilter.m_Mesh.TryGet(out var m_Mesh)) { if (!fbxInfoDic.ContainsKey(m_Mesh)) { fbxInfoDic.Add(m_Mesh, m_GameObject); } } } if (m_GameObject.m_SkinnedMeshRenderer != null) { if (m_GameObject.m_SkinnedMeshRenderer.m_Mesh.TryGet(out var m_Mesh)) { if (!fbxInfoDic.ContainsKey(m_Mesh)) { fbxInfoDic.Add(m_Mesh, m_GameObject); } } } break; case Texture2D m_Texture2D: if (!string.IsNullOrEmpty(m_Texture2D.m_StreamData?.path)) { assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size; } assetItem.Text = m_Texture2D.m_Name; exportable = true; assetsInfoList.Add(string.Format("{0}|{1}|{2}", assetItem.Text, assetItem.TypeString, assetItem.FullSize)); break; case AudioClip m_AudioClip: if (!string.IsNullOrEmpty(m_AudioClip.m_Source)) { assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size; } assetItem.Text = m_AudioClip.m_Name; exportable = true; break; case VideoClip m_VideoClip: if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath)) { assetItem.FullSize = asset.byteSize + (long)m_VideoClip.m_Size; } assetItem.Text = m_VideoClip.m_Name; exportable = true; break; case Shader m_Shader: assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name; exportable = true; break; case Mesh _: assetItem.Text = ((NamedObject)asset).m_Name; exportable = true; meshTmpInfoList.Add(new MeshTmpInfo(asset, assetItem.TypeString, assetItem.FullSize)); break; case TextAsset _: case AnimationClip _: case Font _: case MovieTexture _: case Sprite _: assetItem.Text = ((NamedObject)asset).m_Name; exportable = true; assetsInfoList.Add(string.Format("{0}|{1}|{2}", assetItem.Text, assetItem.TypeString, assetItem.FullSize)); break; case Animator m_Animator: if (m_Animator.m_GameObject.TryGet(out var gameObject)) { assetItem.Text = gameObject.m_Name; } exportable = true; break; case MonoBehaviour m_MonoBehaviour: if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var m_Script)) { assetItem.Text = m_Script.m_ClassName; } else { assetItem.Text = m_MonoBehaviour.m_Name; } exportable = true; break; case PlayerSettings m_PlayerSettings: productName = m_PlayerSettings.productName; break; case AssetBundle m_AssetBundle: ab = m_AssetBundle; assetItem.Text = ab.m_Name; break; case NamedObject m_NamedObject: assetItem.Text = m_NamedObject.m_Name; break; } if (assetItem.Text == "") { assetItem.Text = assetItem.TypeString + assetItem.UniqueID; } assetItem.SubItems.AddRange(new[] { assetItem.TypeString, assetItem.FullSize.ToString() }); //处理同名文件 if (!assetsNameHash.Add((assetItem.TypeString + assetItem.Text).ToUpper())) { assetItem.Text += assetItem.UniqueID; } //处理非法文件名 assetItem.Text = FixFileName(assetItem.Text); if (displayAll) { exportable = true; } if (exportable) { tempExportableAssets.Add(assetItem); } Progress.Report(++j, progressCount); } if (displayOriginalName && ab != null) { foreach (var item in tempExportableAssets) { var originalPath = ab.m_Container.FirstOrDefault(y => y.Value.asset.m_PathID == item.Asset.m_PathID).Key; if (!string.IsNullOrEmpty(originalPath)) { var extension = Path.GetExtension(originalPath); if (!string.IsNullOrEmpty(extension) && item.Type == ClassIDType.TextAsset) { item.Extension = extension; } item.Text = Path.GetDirectoryName(originalPath) + "\\" + Path.GetFileNameWithoutExtension(originalPath); if (!assetsNameHash.Add((item.TypeString + item.Text).ToUpper())) { item.Text += item.UniqueID; } } } } exportableAssets.AddRange(tempExportableAssets); tempExportableAssets.Clear(); if (meshTmpInfoList.Count > 0) { var parentGameObjectInfoDic = new Dictionary <GameObject, MeshTmpInfo>(); foreach (var meshTmpInfo in meshTmpInfoList) { Object fbxObj; if (fbxInfoDic.TryGetValue(meshTmpInfo.m_object, out fbxObj)) { GameObject fbxGameObj = (GameObject)fbxObj; if (fbxGameObj.m_Transform.m_Father.TryGet(out var m_Father)) { if (m_Father.m_GameObject.TryGet(out var parentGameObject)) { if (parentGameObjectInfoDic.ContainsKey(parentGameObject)) { parentGameObjectInfoDic[parentGameObject].m_size += meshTmpInfo.m_size; } else { parentGameObjectInfoDic.Add(parentGameObject, new MeshTmpInfo(parentGameObject, meshTmpInfo.m_type, meshTmpInfo.m_size)); } } } else { assetsInfoList.Add(string.Format("{0}|{1}|{2}", ((GameObject)fbxObj).m_Name, meshTmpInfo.m_type, meshTmpInfo.m_size)); } } else { assetsInfoList.Add(string.Format("{0}|{1}|{2}", ((NamedObject)meshTmpInfo.m_object).m_Name, meshTmpInfo.m_type, meshTmpInfo.m_size)); } } foreach (var parentInfo in parentGameObjectInfoDic) { GameObject parentObj = (GameObject)parentInfo.Value.m_object; assetsInfoList.Add(string.Format("{0}|{1}|{2}", parentObj.m_Name, parentInfo.Value.m_type, parentInfo.Value.m_size)); } } if (assetsInfoList.Count > 0) { string filePath = assetsFile.originalPath; filePath = filePath.Substring(filePath.LastIndexOf("\\") + 1); if (allAssetsInfoDic.ContainsKey(filePath)) { List <string> infoList = allAssetsInfoDic[filePath]; foreach (string info in assetsInfoList) { infoList.Add(info); } } else { allAssetsInfoDic.Add(filePath, assetsInfoList); } } } visibleAssets = exportableAssets; assetsNameHash.Clear(); try { Stream stream = new FileStream(OutPutPath + "/AssetInfo.bin", FileMode.Create, FileAccess.ReadWrite); BinaryFormatter binFormat = new BinaryFormatter(); binFormat.Serialize(stream, allAssetsInfoDic); stream.Close(); stream.Dispose(); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
public static bool ExportMesh(AssetItem item, string exportPath) { var m_Mesh = (Mesh)item.Asset; if (m_Mesh.m_VertexCount <= 0) { return(false); } if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath)) { return(false); } var sb = new StringBuilder(); sb.AppendLine("g " + m_Mesh.m_Name); #region Vertices if (m_Mesh.m_Vertices == null || m_Mesh.m_Vertices.Length == 0) { return(false); } int c = 3; if (m_Mesh.m_Vertices.Length == m_Mesh.m_VertexCount * 4) { c = 4; } for (int v = 0; v < m_Mesh.m_VertexCount; v++) { sb.AppendFormat("v {0} {1} {2}\r\n", -m_Mesh.m_Vertices[v * c], m_Mesh.m_Vertices[v * c + 1], m_Mesh.m_Vertices[v * c + 2]); } #endregion #region UV if (m_Mesh.m_UV0?.Length > 0) { if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 2) { c = 2; } else if (m_Mesh.m_UV0.Length == m_Mesh.m_VertexCount * 3) { c = 3; } for (int v = 0; v < m_Mesh.m_VertexCount; v++) { sb.AppendFormat("vt {0} {1}\r\n", m_Mesh.m_UV0[v * c], m_Mesh.m_UV0[v * c + 1]); } } #endregion #region Normals if (m_Mesh.m_Normals?.Length > 0) { if (m_Mesh.m_Normals.Length == m_Mesh.m_VertexCount * 3) { c = 3; } else if (m_Mesh.m_Normals.Length == m_Mesh.m_VertexCount * 4) { c = 4; } for (int v = 0; v < m_Mesh.m_VertexCount; v++) { sb.AppendFormat("vn {0} {1} {2}\r\n", -m_Mesh.m_Normals[v * c], m_Mesh.m_Normals[v * c + 1], m_Mesh.m_Normals[v * c + 2]); } } #endregion #region Face int sum = 0; for (var i = 0; i < m_Mesh.m_SubMeshes.Length; i++) { sb.AppendLine($"g {m_Mesh.m_Name}_{i}"); int indexCount = (int)m_Mesh.m_SubMeshes[i].indexCount; var end = sum + indexCount / 3; for (int f = sum; f < end; f++) { sb.AppendFormat("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\r\n", m_Mesh.m_Indices[f * 3 + 2] + 1, m_Mesh.m_Indices[f * 3 + 1] + 1, m_Mesh.m_Indices[f * 3] + 1); } sum = end; } #endregion sb.Replace("NaN", "0"); File.WriteAllText(exportFullPath, sb.ToString()); return(true); }
public static (string, List <TreeNode>) BuildAssetData() { StatusStripUpdate("Building asset list..."); string productName = null; var assetsNameHash = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count); var objectAssetItemDic = new Dictionary <Object, AssetItem>(objectCount); int i = 0; Progress.Reset(); foreach (var assetsFile in assetsManager.assetsFileList) { var tempExportableAssets = new List <AssetItem>(); Dictionary <long, string> containers = null; foreach (var asset in assetsFile.Objects) { var assetItem = new AssetItem(asset); objectAssetItemDic.Add(asset, assetItem); assetItem.UniqueID = " #" + i; var exportable = false; switch (asset) { case GameObject m_GameObject: assetItem.Text = m_GameObject.m_Name; break; case Texture2D m_Texture2D: if (!string.IsNullOrEmpty(m_Texture2D.m_StreamData?.path)) { assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size; } assetItem.Text = m_Texture2D.m_Name; exportable = true; break; case AudioClip m_AudioClip: if (!string.IsNullOrEmpty(m_AudioClip.m_Source)) { assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size; } assetItem.Text = m_AudioClip.m_Name; exportable = true; break; case VideoClip m_VideoClip: if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath)) { assetItem.FullSize = asset.byteSize + (long)m_VideoClip.m_Size; } assetItem.Text = m_VideoClip.m_Name; exportable = true; break; case Shader m_Shader: assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name; exportable = true; break; case Mesh _: case TextAsset _: case AnimationClip _: case Font _: case MovieTexture _: case Sprite _: assetItem.Text = ((NamedObject)asset).m_Name; exportable = true; break; case Animator m_Animator: if (m_Animator.m_GameObject.TryGet(out var gameObject)) { assetItem.Text = gameObject.m_Name; } exportable = true; break; case MonoBehaviour m_MonoBehaviour: if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var m_Script)) { assetItem.Text = m_Script.m_ClassName; } else { assetItem.Text = m_MonoBehaviour.m_Name; } if (assetsFile.singleFile) { assetItem.Text = assetsFile.fileName; } exportable = true; break; case PlayerSettings m_PlayerSettings: productName = m_PlayerSettings.productName; break; case AssetBundle m_AssetBundle: containers = new Dictionary <long, string>(); foreach (var m_Container in m_AssetBundle.m_Container) { containers[m_Container.Value.asset.m_PathID] = m_Container.Key; } assetItem.Text = m_AssetBundle.m_Name; break; case NamedObject m_NamedObject: assetItem.Text = m_NamedObject.m_Name; break; } if (assetItem.Text == "") { assetItem.Text = assetItem.TypeString + assetItem.UniqueID; } //处理同名文件 if (!assetsNameHash.Add(assetItem.TypeString + assetItem.Text)) { assetItem.Text += assetItem.UniqueID; } //处理非法文件名 assetItem.Text = FixFileName(assetItem.Text); if (Properties.Settings.Default.displayAll || exportable) { tempExportableAssets.Add(assetItem); } Progress.Report(++i, objectCount); } foreach (var item in tempExportableAssets) { if (containers != null) { if (containers.TryGetValue(item.Asset.m_PathID, out var container)) { if (!string.IsNullOrEmpty(container)) { item.Container = container; } } } item.SetSubItems(); } exportableAssets.AddRange(tempExportableAssets); tempExportableAssets.Clear(); containers?.Clear(); } visibleAssets = exportableAssets; assetsNameHash.Clear(); StatusStripUpdate("Building tree structure..."); var treeNodeCollection = new List <TreeNode>(); var treeNodeDictionary = new Dictionary <GameObject, GameObjectTreeNode>(); var assetsFileCount = assetsManager.assetsFileList.Count; int j = 0; Progress.Reset(); foreach (var assetsFile in assetsManager.assetsFileList) { var fileNode = new GameObjectTreeNode(assetsFile.fileName); //RootNode foreach (var obj in assetsFile.Objects) { if (obj is GameObject m_GameObject) { if (!treeNodeDictionary.TryGetValue(m_GameObject, out var currentNode)) { currentNode = new GameObjectTreeNode(m_GameObject); treeNodeDictionary.Add(m_GameObject, currentNode); } foreach (var pptr in m_GameObject.m_Components) { if (pptr.TryGet(out var m_Component)) { objectAssetItemDic[m_Component].TreeNode = currentNode; if (m_Component is MeshFilter m_MeshFilter) { if (m_MeshFilter.m_Mesh.TryGet(out var m_Mesh)) { objectAssetItemDic[m_Mesh].TreeNode = currentNode; } } else if (m_Component is SkinnedMeshRenderer m_SkinnedMeshRenderer) { if (m_SkinnedMeshRenderer.m_Mesh.TryGet(out var m_Mesh)) { objectAssetItemDic[m_Mesh].TreeNode = currentNode; } } } } var parentNode = fileNode; if (m_GameObject.m_Transform != null) { if (m_GameObject.m_Transform.m_Father.TryGet(out var m_Father)) { if (m_Father.m_GameObject.TryGet(out var parentGameObject)) { if (!treeNodeDictionary.TryGetValue(parentGameObject, out parentNode)) { parentNode = new GameObjectTreeNode(parentGameObject); treeNodeDictionary.Add(parentGameObject, parentNode); } } } } parentNode.Nodes.Add(currentNode); } } if (fileNode.Nodes.Count > 0) { treeNodeCollection.Add(fileNode); } Progress.Report(++j, assetsFileCount); } treeNodeDictionary.Clear(); objectAssetItemDic.Clear(); return(productName, treeNodeCollection); }
public static void BuildAssetList(Dictionary <Object, AssetItem> tempDic, bool displayAll, bool displayOriginalName, out string productName) { Logger.Info("Building asset list..."); productName = string.Empty; var assetsNameHash = new HashSet <string>(); var progressCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count); int j = 0; Progress.Reset(); foreach (var assetsFile in assetsManager.assetsFileList) { var tempExportableAssets = new List <AssetItem>(); AssetBundle ab = null; foreach (var asset in assetsFile.Objects.Values) { var assetItem = new AssetItem(asset); tempDic.Add(asset, assetItem); assetItem.UniqueID = " #" + j; var exportable = false; switch (asset) { case GameObject m_GameObject: assetItem.Text = m_GameObject.m_Name; break; case Texture2D m_Texture2D: if (!string.IsNullOrEmpty(m_Texture2D.m_StreamData?.path)) { assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size; } assetItem.Text = m_Texture2D.m_Name; exportable = true; break; case AudioClip m_AudioClip: if (!string.IsNullOrEmpty(m_AudioClip.m_Source)) { assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size; } assetItem.Text = m_AudioClip.m_Name; exportable = true; break; case VideoClip m_VideoClip: if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath)) { assetItem.FullSize = asset.byteSize + (long)m_VideoClip.m_Size; } assetItem.Text = m_VideoClip.m_Name; exportable = true; break; case Shader m_Shader: assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name; exportable = true; break; case Mesh _: case TextAsset _: case AnimationClip _: case Font _: case MovieTexture _: case Sprite _: assetItem.Text = ((NamedObject)asset).m_Name; exportable = true; break; case Animator m_Animator: if (m_Animator.m_GameObject.TryGet(out var gameObject)) { assetItem.Text = gameObject.m_Name; } exportable = true; break; case MonoBehaviour m_MonoBehaviour: if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var m_Script)) { assetItem.Text = m_Script.m_ClassName; } else { assetItem.Text = m_MonoBehaviour.m_Name; } exportable = true; break; case PlayerSettings m_PlayerSettings: productName = m_PlayerSettings.productName; break; case AssetBundle m_AssetBundle: ab = m_AssetBundle; assetItem.Text = ab.m_Name; break; case SpriteAtlas m_SpriteAtlas: foreach (var m_PackedSprite in m_SpriteAtlas.m_PackedSprites) { if (m_PackedSprite.TryGet(out var m_Sprite)) { if (m_Sprite.m_SpriteAtlas.IsNull()) { m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas); } } } break; case NamedObject m_NamedObject: assetItem.Text = m_NamedObject.m_Name; break; } if (assetItem.Text == "") { assetItem.Text = assetItem.TypeString + assetItem.UniqueID; } assetItem.SubItems.AddRange(new[] { assetItem.TypeString, assetItem.FullSize.ToString() }); //处理同名文件 if (!assetsNameHash.Add((assetItem.TypeString + assetItem.Text).ToUpper())) { assetItem.Text += assetItem.UniqueID; } //处理非法文件名 assetItem.Text = FixFileName(assetItem.Text); if (displayAll) { exportable = true; } if (exportable) { tempExportableAssets.Add(assetItem); } Progress.Report(++j, progressCount); } if (displayOriginalName && ab != null) { foreach (var item in tempExportableAssets) { var originalPath = ab.m_Container.FirstOrDefault(y => y.Value.asset.m_PathID == item.Asset.m_PathID).Key; if (!string.IsNullOrEmpty(originalPath)) { var extension = Path.GetExtension(originalPath); if (!string.IsNullOrEmpty(extension) && item.Type == ClassIDType.TextAsset) { item.Extension = extension; } item.Text = Path.GetDirectoryName(originalPath) + "\\" + Path.GetFileNameWithoutExtension(originalPath); if (!assetsNameHash.Add((item.TypeString + item.Text).ToUpper())) { item.Text += item.UniqueID; } } } } exportableAssets.AddRange(tempExportableAssets); tempExportableAssets.Clear(); } visibleAssets = exportableAssets; assetsNameHash.Clear(); }
public static (string, List <TreeNode>) BuildAssetData() { StatusStripUpdate("Building asset list..."); string productName = null; var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count); var objectAssetItemDic = new Dictionary <Object, AssetItem>(objectCount); var containers = new List <(PPtr <Object>, string)>(); int i = 0; Progress.Reset(); foreach (var assetsFile in assetsManager.assetsFileList) { foreach (var asset in assetsFile.Objects) { var assetItem = new AssetItem(asset); objectAssetItemDic.Add(asset, assetItem); assetItem.UniqueID = " #" + i; var exportable = false; switch (asset) { case GameObject m_GameObject: assetItem.Text = m_GameObject.m_Name; break; case Texture2D m_Texture2D: if (!string.IsNullOrEmpty(m_Texture2D.m_StreamData?.path)) { assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size; } assetItem.Text = m_Texture2D.m_Name; exportable = true; break; case AudioClip m_AudioClip: if (!string.IsNullOrEmpty(m_AudioClip.m_Source)) { assetItem.FullSize = asset.byteSize + m_AudioClip.m_Size; } assetItem.Text = m_AudioClip.m_Name; exportable = true; break; case VideoClip m_VideoClip: if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath)) { assetItem.FullSize = asset.byteSize + (long)m_VideoClip.m_Size; } assetItem.Text = m_VideoClip.m_Name; exportable = true; break; case Shader m_Shader: assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name; exportable = true; break; case Mesh _: case TextAsset _: case AnimationClip _: case Font _: case MovieTexture _: case Sprite _: assetItem.Text = ((NamedObject)asset).m_Name; exportable = true; break; case Animator m_Animator: if (m_Animator.m_GameObject.TryGet(out var gameObject)) { assetItem.Text = gameObject.m_Name; } exportable = true; break; case MonoBehaviour m_MonoBehaviour: if (m_MonoBehaviour.m_Name == "" && m_MonoBehaviour.m_Script.TryGet(out var m_Script)) { assetItem.Text = m_Script.m_ClassName; } else { assetItem.Text = m_MonoBehaviour.m_Name; } exportable = true; break; case PlayerSettings m_PlayerSettings: productName = m_PlayerSettings.productName; break; case AssetBundle m_AssetBundle: foreach (var m_Container in m_AssetBundle.m_Container) { var preloadIndex = m_Container.Value.preloadIndex; var preloadSize = m_Container.Value.preloadSize; var preloadEnd = preloadIndex + preloadSize; for (int k = preloadIndex; k < preloadEnd; k++) { containers.Add((m_AssetBundle.m_PreloadTable[k], m_Container.Key)); } } assetItem.Text = m_AssetBundle.m_Name; break; case ResourceManager m_ResourceManager: foreach (var m_Container in m_ResourceManager.m_Container) { containers.Add((m_Container.Value, m_Container.Key)); } break; case NamedObject m_NamedObject: assetItem.Text = m_NamedObject.m_Name; break; } if (assetItem.Text == "") { assetItem.Text = assetItem.TypeString + assetItem.UniqueID; } if (Properties.Settings.Default.displayAll || exportable) { exportableAssets.Add(assetItem); } Progress.Report(++i, objectCount); } } foreach ((var pptr, var container) in containers) { if (pptr.TryGet(out var obj)) { objectAssetItemDic[obj].Container = container; } } foreach (var tmp in exportableAssets) { tmp.SetSubItems(); } containers.Clear(); visibleAssets = exportableAssets; StatusStripUpdate("Building tree structure..."); var treeNodeCollection = new List <TreeNode>(); var treeNodeDictionary = new Dictionary <GameObject, GameObjectTreeNode>(); var assetsFileCount = assetsManager.assetsFileList.Count; int j = 0; Progress.Reset(); foreach (var assetsFile in assetsManager.assetsFileList) { var fileNode = new GameObjectTreeNode(assetsFile.fileName); //RootNode foreach (var obj in assetsFile.Objects) { if (obj is GameObject m_GameObject) { if (!treeNodeDictionary.TryGetValue(m_GameObject, out var currentNode)) { currentNode = new GameObjectTreeNode(m_GameObject); treeNodeDictionary.Add(m_GameObject, currentNode); } foreach (var pptr in m_GameObject.m_Components) { if (pptr.TryGet(out var m_Component)) { objectAssetItemDic[m_Component].TreeNode = currentNode; if (m_Component is MeshFilter m_MeshFilter) { if (m_MeshFilter.m_Mesh.TryGet(out var m_Mesh)) { objectAssetItemDic[m_Mesh].TreeNode = currentNode; } } else if (m_Component is SkinnedMeshRenderer m_SkinnedMeshRenderer) { if (m_SkinnedMeshRenderer.m_Mesh.TryGet(out var m_Mesh)) { objectAssetItemDic[m_Mesh].TreeNode = currentNode; } } } } var parentNode = fileNode; if (m_GameObject.m_Transform != null) { if (m_GameObject.m_Transform.m_Father.TryGet(out var m_Father)) { if (m_Father.m_GameObject.TryGet(out var parentGameObject)) { if (!treeNodeDictionary.TryGetValue(parentGameObject, out parentNode)) { parentNode = new GameObjectTreeNode(parentGameObject); treeNodeDictionary.Add(parentGameObject, parentNode); } } } } parentNode.Nodes.Add(currentNode); } } if (fileNode.Nodes.Count > 0) { treeNodeCollection.Add(fileNode); } Progress.Report(++j, assetsFileCount); } treeNodeDictionary.Clear(); objectAssetItemDic.Clear(); return(productName, treeNodeCollection); }