public static void PrintToExcel(string outputPath) { EditorUtility.DisplayProgressBar("AssetBundle报告", "正在写入 Excel 文件...", 0.85f); var newFile = new FileInfo(outputPath); if (newFile.Exists) { newFile.Delete(); } using (var package = new ExcelPackage(newFile)) { AssetBundleFilesReporter.CreateWorksheet(package.Workbook.Worksheets); AssetBundleDetailsReporter.CreateWorksheet(package.Workbook.Worksheets); AssetBundleResReporter.CreateWorksheet(package.Workbook.Worksheets); AssetBundleFilesReporter.FillWorksheet(package.Workbook.Worksheets[1]); AssetBundleDetailsReporter.FillWorksheet(package.Workbook.Worksheets[2]); AssetBundleResReporter.FillWorksheet(package.Workbook.Worksheets[3]); AssetBundlePropertyReporter.CreateAndFillWorksheet(package.Workbook.Worksheets, AssetFileInfoType.mesh); AssetBundlePropertyReporter.CreateAndFillWorksheet(package.Workbook.Worksheets, AssetFileInfoType.texture2D); AssetBundlePropertyReporter.CreateAndFillWorksheet(package.Workbook.Worksheets, AssetFileInfoType.material); AssetBundlePropertyReporter.CreateAndFillWorksheet(package.Workbook.Worksheets, AssetFileInfoType.animationClip); AssetBundlePropertyReporter.CreateAndFillWorksheet(package.Workbook.Worksheets, AssetFileInfoType.audioClip); package.Save(); } AssetBundleFilesAnalyze.Clear(); EditorUtility.ClearProgressBar(); }
public static void FillWorksheet(ExcelWorksheet ws) { int startRow = 2; List <AssetBundleFileInfo> infos = AssetBundleFilesAnalyze.GetAllAssetBundleFileInfos(); foreach (var info in infos) { ws.Cells[startRow, 1].Value = info.name + " 所包含的具体资源"; using (var range = ws.Cells[startRow, 1, startRow, 4]) { range.Merge = true; range.Style.Font.Bold = true; range.Style.Fill.PatternType = ExcelFillStyle.Solid; range.Style.Fill.BackgroundColor.SetColor(ColorTranslator.FromHtml("#BDD7EE")); } info.detailHyperLink.ReferenceAddress = ws.Cells[startRow, 1].FullAddress; FillAssetByType(info, AssetFileInfoType.mesh, ws, ref startRow); FillAssetByType(info, AssetFileInfoType.material, ws, ref startRow); FillAssetByType(info, AssetFileInfoType.texture2D, ws, ref startRow); FillAssetByType(info, AssetFileInfoType.sprite, ws, ref startRow); FillAssetByType(info, AssetFileInfoType.shader, ws, ref startRow); FillAssetByType(info, AssetFileInfoType.animatorController, ws, ref startRow); FillAssetByType(info, AssetFileInfoType.animatorOverrideController, ws, ref startRow); FillAssetByType(info, AssetFileInfoType.animationClip, ws, ref startRow); FillAssetByType(info, AssetFileInfoType.audioClip, ws, ref startRow); FillAssetByType(info, AssetFileInfoType.monoScript, ws, ref startRow); FillAssetDepends(info, ws, ref startRow); startRow += 6; } }
private IEnumerator AnalyzeBundleScene(Scene scene) { yield return(new WaitForEndOfFrame()); Scene defaultScene = SceneManager.GetActiveScene(); SceneManager.SetActiveScene(scene); BundleSceneInfo info = m_BundleSceneInfos.Peek(); if (info.sceneName != scene.name) { Debug.LogError("What's scene? " + scene.path); yield break; } AssetBundleFilesAnalyze.AnalyzeObjectReference(info.fileInfo, RenderSettings.skybox); GameObject[] gos = scene.GetRootGameObjects(); foreach (var go in gos) { AssetBundleFilesAnalyze.AnalyzeObjectComponent(info.fileInfo, go); } AssetBundleFilesAnalyze.AnalyzeObjectsCompleted(info.fileInfo); SceneManager.SetActiveScene(defaultScene); info.ab.Unload(true); info.ab = null; SceneManager.UnloadScene(scene); }
/// <summary> /// 分析打印 AssetBundle /// </summary> /// <param name="bundlePath">AssetBundle 文件所在文件夹路径</param> /// <param name="outputPath">Excel 报告文件保存路径</param> /// <param name="completed">分析打印完毕后的回调</param> public static void AnalyzePrint(string bundlePath, string outputPath, UnityAction completed = null) { AssetBundleFilesAnalyze.analyzeCompleted = () => { PrintToExcel(outputPath); if (completed != null) { completed(); } }; EditorUtility.DisplayProgressBar("AssetBundle报告", "正在分析 AssetBundle 文件...", 0.35f); if (!AssetBundleFilesAnalyze.Analyze(bundlePath)) { EditorUtility.ClearProgressBar(); } }
public static void FillWorksheet(ExcelWorksheet ws) { int startRow = 3; int maxCol = 4; var dicts = AssetBundleFilesAnalyze.GetAllAssetFileInfo(); if (dicts == null) { ws.Cells[1, 1].Value = ws.Cells[1, 1].Value + " (0)"; } else { foreach (var info in dicts.Values) { ws.Cells[startRow, 1].Value = info.name; ws.Cells[startRow, 2].Value = info.type; ws.Cells[startRow, 3].Value = info.includedBundles.Count; info.detailHyperLink.ReferenceAddress = ws.Cells[startRow, 1].FullAddress; int startCol = 4; foreach (var bundleFileInfo in info.includedBundles) { ws.Cells[startRow, startCol].Value = bundleFileInfo.name; ws.Cells[startRow, startCol++].Hyperlink = bundleFileInfo.detailHyperLink; } maxCol = System.Math.Max(--startCol, maxCol); startRow++; } ws.Cells[1, 1].Value = ws.Cells[1, 1].Value + " (" + dicts.Values.Count + ")"; } // 具体所需要的列 using (var range = ws.Cells[2, 4, 2, maxCol]) { range.Merge = true; } for (int i = 4; i <= maxCol; i++) { ws.Column(i).Width = 100; } }
private void LoadNextBundleScene() { if (m_BundleSceneInfos.Count <= 0) { SceneManager.sceneLoaded -= SceneManagerOnSceneLoaded; SceneManager.sceneUnloaded -= SceneManagerOnSceneUnloaded; if (AssetBundleFilesAnalyze.analyzeCompleted != null) { AssetBundleFilesAnalyze.analyzeCompleted(); } return; } // 释放一下内存,以免爆掉 Resources.UnloadUnusedAssets(); GC.Collect(); BundleSceneInfo info = m_BundleSceneInfos.Peek(); info.ab = AssetBundle.LoadFromFile(info.fileInfo.path); SceneManager.LoadScene(info.sceneName, LoadSceneMode.Additive); }
private static void FillAssetDepends(AssetBundleFileInfo info, ExcelWorksheet ws, ref int startRow) { if (info.allDepends == null && info.beDepends == null) { return; } if (info.allDepends != null && info.beDepends != null && info.allDepends.Length == 0 && info.beDepends.Length == 0) { return; } int rowAdd = 0; int titleRow = ++startRow; if (info.allDepends != null && info.allDepends.Length != 0) { ws.Cells[titleRow, 3].Value = "它依赖哪些AssetBundle文件? (" + info.allDepends.Length + ")"; SetRangeStyle(ws.Cells[titleRow, 3, titleRow, 4]); int dependRow = titleRow; foreach (var depend in info.allDepends) { if (string.IsNullOrEmpty(depend)) { continue; } dependRow++; var dependInfo = AssetBundleFilesAnalyze.GetAssetBundleFileInfo(depend); ws.Cells[dependRow, 3].Value = dependInfo.name; ws.Cells[dependRow, 3].Hyperlink = dependInfo.detailHyperLink; ws.Cells[dependRow, 3, dependRow, 4].Merge = true; } rowAdd = dependRow - titleRow; } if (info.beDepends != null && info.beDepends.Length != 0) { ws.Cells[titleRow, 1].Value = "哪些AssetBundle文件依赖它? (" + info.beDepends.Length + ")"; SetRangeStyle(ws.Cells[titleRow, 1, titleRow, 2]); int dependRow = titleRow; foreach (var depend in info.beDepends) { dependRow++; var dependInfo = AssetBundleFilesAnalyze.GetAssetBundleFileInfo(depend); ws.Cells[dependRow, 1].Value = dependInfo.name; ws.Cells[dependRow, 1].Hyperlink = dependInfo.detailHyperLink; ws.Cells[dependRow, 1, dependRow, 2].Merge = true; } int rowAdd2 = dependRow - titleRow; if (rowAdd2 > rowAdd) { rowAdd = rowAdd2; } } startRow += rowAdd; }
public static void FillWorksheet(ExcelWorksheet ws) { int startRow = 3; List <AssetBundleFileInfo> infos = AssetBundleFilesAnalyze.GetAllAssetBundleFileInfos(); foreach (var info in infos) { int colIndex = 1; ws.Cells[startRow, colIndex].Value = info.name; info.detailHyperLink = new ExcelHyperLink(String.Empty, info.name); ws.Cells[startRow, colIndex++].Hyperlink = info.detailHyperLink; ws.Cells[startRow, colIndex++].Value = info.size; int count = info.allDepends.Length; if (count > 0) { ws.Cells[startRow, colIndex].Value = count; } colIndex++; count = 0; foreach (var asset in info.assets) { if (asset.includedBundles.Count > 1 && asset.type != AssetFileInfoType.monoScript) { count++; } } if (count > 0) { ws.Cells[startRow, colIndex].Value = count; } colIndex++; count = info.GetAssetCount(AssetFileInfoType.mesh); if (count > 0) { ws.Cells[startRow, colIndex].Value = count; } colIndex++; count = info.GetAssetCount(AssetFileInfoType.material); if (count > 0) { ws.Cells[startRow, colIndex].Value = count; } colIndex++; count = info.GetAssetCount(AssetFileInfoType.texture2D); if (count > 0) { ws.Cells[startRow, colIndex].Value = count; } colIndex++; count = info.GetAssetCount(AssetFileInfoType.sprite); if (count > 0) { ws.Cells[startRow, colIndex].Value = count; } colIndex++; count = info.GetAssetCount(AssetFileInfoType.shader); if (count > 0) { ws.Cells[startRow, colIndex].Value = count; } colIndex++; count = info.GetAssetCount(AssetFileInfoType.animationClip); if (count > 0) { ws.Cells[startRow, colIndex].Value = count; } colIndex++; count = info.GetAssetCount(AssetFileInfoType.audioClip); if (count > 0) { ws.Cells[startRow, colIndex].Value = count; } startRow++; } ws.Cells[1, 1].Value = ws.Cells[1, 1].Value + " (" + infos.Count + ")"; }
public static void ObjectAddToFileInfo(Object o, SerializedObject serializedObject, AssetBundleFileInfo info) { if (!o) { return; } string name2 = o.name; string type = o.GetType().ToString(); if (type.StartsWith("UnityEngine.")) { type = type.Substring(12); // 如果是内置的组件,就不当作是资源 if (o as Component) { return; } } else if (type == "UnityEditor.Animations.AnimatorController") { type = "AnimatorController"; } else if (type == "UnityEditorInternal.AnimatorController") { type = "AnimatorController"; } else if (type == "UnityEditor.MonoScript") { MonoScript ms = o as MonoScript; string type2 = ms.GetClass().ToString(); if (type2.StartsWith("UnityEngine.")) { // 内置的脚本对象也不显示出来 return; } // 外部的组件脚本,保留下来 type = "MonoScript"; } else { // 外部的组件脚本,走上面的MonoScript if (o as Component) { return; } // 外部的序列化对象,已经被脚本给分析完毕了,不需要再添加进来 if (o as ScriptableObject) { return; } Debug.LogError("What's this? " + type); return; } // 内建的资源排除掉 string assetPath = AssetDatabase.GetAssetPath(o); if (!string.IsNullOrEmpty(assetPath)) { return; } long guid; if (info.isScene) { // 场景的话,没法根据PathID来确定唯一性,那么就认为每个场景用到的资源都不一样 guid = (info.name + name2 + type).GetHashCode(); } else { SerializedProperty pathIdProp = serializedObject.FindProperty("m_LocalIdentfierInFile"); #if UNITY_5 || UNITY_5_3_OR_NEWER guid = pathIdProp.longValue; #else guid = pathIdProp.intValue; #endif } if (info.IsAssetContain(guid)) { return; } AssetFileInfo info2 = AssetBundleFilesAnalyze.GetAssetFileInfo(guid); info2.name = name2; info2.type = type; info2.includedBundles.Add(info); if (info2.detailHyperLink == null) { // 初次创建对象时链接为空 info2.detailHyperLink = new OfficeOpenXml.ExcelHyperLink(System.String.Empty, info2.name); info2.propertys = AnalyzeObject(o, serializedObject, info.rootPath, info.name); } info.assets.Add(info2); }
public static void CreateAndFillWorksheet(ExcelWorksheets wss, string typeName) { var dicts = AssetBundleFilesAnalyze.GetAllAssetFileInfo(); if (dicts == null) { return; } List <string> columnNames = new List <string>(); foreach (var info in dicts.Values) { if (info.type != typeName) { continue; } foreach (var pair in info.propertys) { columnNames.Add(pair.Key); } break; } if (columnNames.Count == 0) { return; } string titleName = typeName + " 列表"; ExcelWorksheet ws = wss.Add(titleName); int abCountCol = columnNames.Count + 2; int abDetailCol = columnNames.Count + 3; // 标签颜色 ws.TabColor = ColorTranslator.FromHtml("#b490f5"); AssetBundleReporter.CreateWorksheetBase(ws, titleName, abDetailCol); // 列头 ws.Cells[2, 1].Value = "资源名称"; for (int i = 0; i < columnNames.Count; i++) { ws.Cells[2, i + 2].Value = columnNames[i]; } ws.Cells[2, abCountCol].Value = "AB文件数量"; ws.Cells[2, abDetailCol].Value = "相应的AB文件"; using (var range = ws.Cells[2, 1, 2, abDetailCol]) { // 字体样式 range.Style.Font.Bold = true; // 背景颜色 range.Style.Fill.PatternType = ExcelFillStyle.Solid; range.Style.Fill.BackgroundColor.SetColor(ColorTranslator.FromHtml("#DDEBF7")); // 开启自动筛选 range.AutoFilter = true; } // 列宽 ws.Column(1).Width = 50; for (int i = 0; i < columnNames.Count; i++) { ws.Column(2 + i).Width = 15; ws.Column(2 + i).Style.HorizontalAlignment = ExcelHorizontalAlignment.Left; ws.Column(2 + i).Style.VerticalAlignment = ExcelVerticalAlignment.Top; } ws.Column(abCountCol).Width = 15; ws.Column(abCountCol).Style.HorizontalAlignment = ExcelHorizontalAlignment.Left; ws.Column(abCountCol).Style.VerticalAlignment = ExcelVerticalAlignment.Top; // 冻结前两行 ws.View.FreezePanes(3, 1); int startRow = 3; int maxCol = abDetailCol; foreach (var info in dicts.Values) { if (info.type != typeName) { continue; } ws.Cells[startRow, 1].Value = info.name; info.detailHyperLink.ReferenceAddress = ws.Cells[startRow, 1].FullAddress; int startCol = 2; foreach (var property in info.propertys) { ws.Cells[startRow, startCol++].Value = property.Value; } ws.Cells[startRow, startCol++].Value = info.includedBundles.Count; foreach (var bundleFileInfo in info.includedBundles) { ws.Cells[startRow, startCol].Value = bundleFileInfo.name; ws.Cells[startRow, startCol++].Hyperlink = bundleFileInfo.detailHyperLink; } maxCol = System.Math.Max(--startCol, maxCol); startRow++; } ws.Cells[1, 1].Value = ws.Cells[1, 1].Value + " (" + (startRow - 3) + ")"; // 具体所需要的列 using (var range = ws.Cells[2, abDetailCol, 2, maxCol]) { range.Merge = true; } for (int i = abDetailCol; i <= maxCol; i++) { ws.Column(i).Width = 100; } // 不同类型不同处理 switch (typeName) { case "Texture2D": ws.Column(7).Style.Numberformat.Format = "#,##0"; break; case "Material": ws.Column(2).Width = 40; ws.Column(3).Width = 50; break; case "AnimationClip": ws.Column(7).Style.Numberformat.Format = "#,##0"; break; case "AudioClip": ws.Column(2).Width = 23; break; } }