#if UNITY_2019_4_OR_NEWER using System; using System.IO; using System.Linq; using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEditor.UIElements; using UnityEngine.UIElements; namespace YooAsset.Editor { internal class ReporterBundleListViewer { private class BundleTableData : DefaultTableData { public ReportBundleInfo BundleInfo; } private class IncludeTableData : DefaultTableData { public ReportAssetInfo AssetInfo; } private VisualTreeAsset _visualAsset; private TemplateContainer _root; private TableViewer _bundleTableView; private TableViewer _includeTableView; private BuildReport _buildReport; private string _reportFilePath; private List _sourceDatas; /// /// 初始化页面 /// public void InitViewer() { // 加载布局文件 _visualAsset = UxmlLoader.LoadWindowUXML(); if (_visualAsset == null) return; _root = _visualAsset.CloneTree(); _root.style.flexGrow = 1f; // 资源包列表 _bundleTableView = _root.Q("TopTableView"); _bundleTableView.ClickTableDataEvent = OnClickBundleTableView; _bundleTableView.SelectionChangedEvent = OnBundleTableViewSelectionChanged; CreateBundleTableViewColumns(); // 包含列表 _includeTableView = _root.Q("BottomTableView"); _includeTableView.ClickTableDataEvent = OnClickIncludeTableView; CreateIncludeTableViewColumns(); #if UNITY_2020_3_OR_NEWER var topGroup = _root.Q("TopGroup"); var bottomGroup = _root.Q("BottomGroup"); topGroup.style.minHeight = 100; bottomGroup.style.minHeight = 100f; UIElementsTools.SplitVerticalPanel(_root, topGroup, bottomGroup); #endif } private void CreateBundleTableViewColumns() { //BundleName { var columnStyle = new ColumnStyle(600, 500, 1000); columnStyle.Stretchable = true; columnStyle.Searchable = true; columnStyle.Sortable = true; columnStyle.Counter = true; var column = new TableColumn("BundleName", "Bundle Name", columnStyle); column.MakeCell = () => { var label = new Label(); label.style.unityTextAlign = TextAnchor.MiddleLeft; return label; }; column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => { var infoLabel = element as Label; infoLabel.text = (string)cell.GetDisplayObject(); }; _bundleTableView.AddColumn(column); } // FileSize { var columnStyle = new ColumnStyle(100); columnStyle.Stretchable = false; columnStyle.Searchable = true; columnStyle.Sortable = true; var column = new TableColumn("FileSize", "File Size", columnStyle); column.MakeCell = () => { var label = new Label(); label.style.unityTextAlign = TextAnchor.MiddleLeft; return label; }; column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => { var infoLabel = element as Label; long fileSize = (long)cell.CellValue; infoLabel.text = EditorUtility.FormatBytes(fileSize); }; _bundleTableView.AddColumn(column); } // FileHash { var columnStyle = new ColumnStyle(250); columnStyle.Stretchable = false; columnStyle.Searchable = false; columnStyle.Sortable = false; var column = new TableColumn("FileHash", "File Hash", columnStyle); column.MakeCell = () => { var label = new Label(); label.style.unityTextAlign = TextAnchor.MiddleLeft; return label; }; column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => { var infoLabel = element as Label; infoLabel.text = (string)cell.GetDisplayObject(); }; _bundleTableView.AddColumn(column); } //Encrypted { var columnStyle = new ColumnStyle(100); columnStyle.Stretchable = false; columnStyle.Searchable = false; columnStyle.Sortable = true; var column = new TableColumn("Encrypted", "Encrypted", columnStyle); column.MakeCell = () => { var label = new Label(); label.style.unityTextAlign = TextAnchor.MiddleLeft; return label; }; column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => { var infoLabel = element as Label; bool encrypted = (bool)cell.CellValue; infoLabel.text = encrypted.ToString(); }; _bundleTableView.AddColumn(column); } //Tags { var columnStyle = new ColumnStyle(150, 100, 1000); columnStyle.Stretchable = true; columnStyle.Searchable = true; columnStyle.Sortable = true; var column = new TableColumn("Tags", "Tags", columnStyle); column.MakeCell = () => { var label = new Label(); label.style.unityTextAlign = TextAnchor.MiddleLeft; return label; }; column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => { var infoLabel = element as Label; infoLabel.text = (string)cell.GetDisplayObject(); }; _bundleTableView.AddColumn(column); } } private void CreateIncludeTableViewColumns() { //IncludeAssets { var columnStyle = new ColumnStyle(600, 500, 1000); columnStyle.Stretchable = true; columnStyle.Searchable = true; columnStyle.Sortable = true; columnStyle.Counter = true; var column = new TableColumn("IncludeAssets", "Include Assets", columnStyle); column.MakeCell = () => { var label = new Label(); label.style.unityTextAlign = TextAnchor.MiddleLeft; return label; }; column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => { var infoLabel = element as Label; infoLabel.text = (string)cell.GetDisplayObject(); }; _includeTableView.AddColumn(column); } //AssetSource { var columnStyle = new ColumnStyle(100); columnStyle.Stretchable = false; columnStyle.Searchable = false; columnStyle.Sortable = false; var column = new TableColumn("AssetSource", "Asset Source", columnStyle); column.MakeCell = () => { var label = new Label(); label.style.unityTextAlign = TextAnchor.MiddleLeft; return label; }; column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => { var infoLabel = element as Label; infoLabel.text = (string)cell.GetDisplayObject(); }; _includeTableView.AddColumn(column); } //AssetGUID { var columnStyle = new ColumnStyle(250); columnStyle.Stretchable = false; columnStyle.Searchable = false; columnStyle.Sortable = false; var column = new TableColumn("AssetGUID", "Asset GUID", columnStyle); column.MakeCell = () => { var label = new Label(); label.style.unityTextAlign = TextAnchor.MiddleLeft; return label; }; column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => { var infoLabel = element as Label; infoLabel.text = (string)cell.GetDisplayObject(); }; _includeTableView.AddColumn(column); } } /// /// 填充页面数据 /// public void FillViewData(BuildReport buildReport, string reprotFilePath) { _buildReport = buildReport; _reportFilePath = reprotFilePath; // 清空旧数据 _bundleTableView.ClearAll(false, true); _includeTableView.ClearAll(false, true); // 填充数据源 _sourceDatas = new List(_buildReport.BundleInfos.Count); foreach (var bundleInfo in _buildReport.BundleInfos) { var rowData = new BundleTableData(); rowData.BundleInfo = bundleInfo; rowData.AddStringValueCell("BundleName", bundleInfo.BundleName); rowData.AddLongValueCell("FileSize", bundleInfo.FileSize); rowData.AddStringValueCell("FileHash", bundleInfo.FileHash); rowData.AddBoolValueCell("Encrypted", bundleInfo.Encrypted); rowData.AddStringValueCell("Tags", string.Join(";", bundleInfo.Tags)); _sourceDatas.Add(rowData); } _bundleTableView.itemsSource = _sourceDatas; // 重建视图 RebuildView(null); } /// /// 重建视图 /// public void RebuildView(string searchKeyWord) { // 搜索匹配 DefaultSearchSystem.Search(_sourceDatas, searchKeyWord); // 重建视图 _bundleTableView.RebuildView(); } /// /// 挂接到父类页面上 /// public void AttachParent(VisualElement parent) { parent.Add(_root); } /// /// 从父类页面脱离开 /// public void DetachParent() { _root.RemoveFromHierarchy(); } private void OnBundleTableViewSelectionChanged(ITableData data) { var bundleTableData = data as BundleTableData; var bundleInfo = bundleTableData.BundleInfo; // 填充包含数据 var sourceDatas = new List(); var mainAssetDic = new HashSet(); foreach (var assetInfo in _buildReport.AssetInfos) { if (assetInfo.MainBundleName == bundleInfo.BundleName) { mainAssetDic.Add(assetInfo.AssetPath); var rowData = new IncludeTableData(); rowData.AssetInfo = assetInfo; rowData.AddAssetPathCell("IncludeAssets", assetInfo.AssetPath); rowData.AddStringValueCell("AssetSource", "MainAsset"); rowData.AddStringValueCell("AssetGUID", assetInfo.AssetGUID); sourceDatas.Add(rowData); } } foreach (var assetInfo in bundleInfo.BundleContents) { if (mainAssetDic.Contains(assetInfo.AssetPath) == false) { var rowData = new IncludeTableData(); rowData.AssetInfo = null; rowData.AddAssetPathCell("IncludeAssets", assetInfo.AssetPath); rowData.AddStringValueCell("AssetSource", "BuiltinAsset"); rowData.AddStringValueCell("AssetGUID", assetInfo.AssetGUID); sourceDatas.Add(rowData); } } _includeTableView.itemsSource = sourceDatas; _includeTableView.RebuildView(); } private void OnClickBundleTableView(PointerDownEvent evt, ITableData data) { // 鼠标双击后检视 if (evt.clickCount != 2) return; var bundleTableData = data as BundleTableData; if (bundleTableData.BundleInfo.Encrypted) return; if (_buildReport.Summary.BuildBundleType == (int)EBuildBundleType.AssetBundle) { string rootDirectory = Path.GetDirectoryName(_reportFilePath); string filePath = $"{rootDirectory}/{bundleTableData.BundleInfo.FileName}"; if (File.Exists(filePath)) Selection.activeObject = AssetBundleRecorder.GetAssetBundle(filePath); else Selection.activeObject = null; } } private void OnClickIncludeTableView(PointerDownEvent evt, ITableData data) { // 鼠标双击后检视 if (evt.clickCount != 2) return; foreach (var cell in data.Cells) { if (cell is AssetPathCell assetPathCell) { if (assetPathCell.PingAssetObject()) break; } } } } } #endif