diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderWindow.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderWindow.cs
index 9fe3019..7bd858a 100644
--- a/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderWindow.cs
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/AssetBundleBuilderWindow.cs
@@ -275,6 +275,7 @@ namespace YooAsset.Editor
buildParameters.PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage;
buildParameters.PackageVersion = _buildVersionField.value;
buildParameters.VerifyBuildingResult = true;
+ buildParameters.AutoAnalyzeRedundancy = true;
buildParameters.ShareAssetPackRule = new DefaultShareAssetPackRule();
buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption;
diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs
index 6802035..0547e34 100644
--- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildAssetInfo.cs
@@ -183,5 +183,27 @@ namespace YooAsset.Editor
}
}
}
+
+ ///
+ /// 判断是否为冗余资源
+ ///
+ public bool IsRedundancyAsset()
+ {
+ if (CollectorType != ECollectorType.None)
+ return false;
+
+ if (IsRawAsset)
+ throw new Exception("Should never get here !");
+
+ return _referenceBundleNames.Count > 1;
+ }
+
+ ///
+ /// 获取关联资源包的数量
+ ///
+ public int GetReferenceBundleCount()
+ {
+ return _referenceBundleNames.Count;
+ }
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapContext.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapContext.cs
index e28666f..3c4e592 100644
--- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapContext.cs
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildMapContext.cs
@@ -10,6 +10,11 @@ namespace YooAsset.Editor
{
private readonly Dictionary _bundleInfoDic = new Dictionary(10000);
+ ///
+ /// 冗余的资源列表
+ ///
+ public readonly List RedundancyInfos= new List(1000);
+
///
/// 参与构建的资源总数
/// 说明:包括主动收集的资源以及其依赖的所有资源
diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs
index a593523..61cce7b 100644
--- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildParameters.cs
@@ -77,6 +77,11 @@ namespace YooAsset.Editor
///
public bool VerifyBuildingResult = false;
+ ///
+ /// 自动分析冗余资源
+ ///
+ public bool AutoAnalyzeRedundancy = true;
+
///
/// 共享资源的打包规则
///
diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/BuildReport.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/BuildReport.cs
index abb174d..9d8f018 100644
--- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/BuildReport.cs
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/BuildReport.cs
@@ -27,6 +27,11 @@ namespace YooAsset.Editor
///
public List BundleInfos = new List();
+ ///
+ /// 冗余的资源列表
+ ///
+ public List RedundancyInfos = new List();
+
///
/// 获取资源包信息类
diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportRedundancyInfo.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportRedundancyInfo.cs
new file mode 100644
index 0000000..0d068f4
--- /dev/null
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportRedundancyInfo.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace YooAsset.Editor
+{
+ [Serializable]
+ public class ReportRedundancyInfo
+ {
+ ///
+ /// 资源路径
+ ///
+ public string AssetPath;
+
+ ///
+ /// 资源类型
+ ///
+ public string AssetType;
+
+ ///
+ /// 资源GUID
+ /// 说明:Meta文件记录的GUID
+ ///
+ public string AssetGUID;
+
+ ///
+ /// 资源文件大小
+ ///
+ public long FileSize;
+
+ ///
+ /// 冗余的资源包数量
+ ///
+ public int Number;
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportRedundancyInfo.cs.meta b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportRedundancyInfo.cs.meta
new file mode 100644
index 0000000..b2c5230
--- /dev/null
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportRedundancyInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7fbb7b27f54d3b0439a951348fd9d785
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportSummary.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportSummary.cs
index 180fe40..509fa3c 100644
--- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportSummary.cs
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildReport/ReportSummary.cs
@@ -22,7 +22,7 @@ namespace YooAsset.Editor
/// 构建时间
///
public string BuildDate;
-
+
///
/// 构建耗时(单位:秒)
///
@@ -63,6 +63,16 @@ namespace YooAsset.Editor
///
public bool UniqueBundleName;
+ ///
+ /// 自动分析冗余
+ ///
+ public bool AutoAnalyzeRedundancy;
+
+ ///
+ /// 共享资源的打包类名称
+ ///
+ public string ShareAssetPackRuleClassName;
+
///
/// 加密服务类名称
///
diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateReport.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateReport.cs
index 3b65c33..1ca62f0 100644
--- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateReport.cs
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskCreateReport.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using UnityEditor;
namespace YooAsset.Editor
@@ -46,6 +47,9 @@ namespace YooAsset.Editor
buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion;
buildReport.Summary.EnableAddressable = buildMapContext.EnableAddressable;
buildReport.Summary.UniqueBundleName = buildMapContext.UniqueBundleName;
+ buildReport.Summary.AutoAnalyzeRedundancy = buildParameters.AutoAnalyzeRedundancy;
+ buildReport.Summary.ShareAssetPackRuleClassName = buildParameters.ShareAssetPackRule == null ?
+ "null" : buildParameters.ShareAssetPackRule.GetType().FullName;
buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ?
"null" : buildParameters.EncryptionServices.GetType().FullName;
@@ -101,6 +105,9 @@ namespace YooAsset.Editor
buildReport.BundleInfos.Add(reportBundleInfo);
}
+ // 冗余资源列表
+ buildReport.RedundancyInfos = new List(buildMapContext.RedundancyInfos);
+
// 序列化文件
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}";
diff --git a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskGetBuildMap.cs b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskGetBuildMap.cs
index 709318f..59876f9 100644
--- a/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskGetBuildMap.cs
+++ b/Assets/YooAsset/Editor/AssetBundleBuilder/BuildTasks/TaskGetBuildMap.cs
@@ -13,8 +13,7 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject();
- var buildParameters = buildParametersContext.Parameters;
- var buildMapContext = CreateBuildMap(buildParameters.BuildMode, buildParameters.ShareAssetPackRule, buildParameters.PackageName);
+ var buildMapContext = CreateBuildMap(buildParametersContext.Parameters);
context.SetContextObject(buildMapContext);
BuildLogger.Log("构建内容准备完毕!");
@@ -25,8 +24,13 @@ namespace YooAsset.Editor
///
/// 资源构建上下文
///
- public BuildMapContext CreateBuildMap(EBuildMode buildMode, IShareAssetPackRule packRule, string packageName)
+ public BuildMapContext CreateBuildMap(BuildParameters buildParameters)
{
+ EBuildMode buildMode = buildParameters.BuildMode;
+ string packageName = buildParameters.PackageName;
+ IShareAssetPackRule sharePackRule = buildParameters.ShareAssetPackRule;
+ bool autoAnalyzeRedundancy = buildParameters.AutoAnalyzeRedundancy;
+
Dictionary allBuildAssetInfoDic = new Dictionary(1000);
// 1. 检测配置合法性
@@ -99,10 +103,30 @@ namespace YooAsset.Editor
context.ShadersBundleName = collectResult.Command.ShadersBundleName;
// 8. 计算共享的资源包名
- var command = collectResult.Command;
- foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
+ if (autoAnalyzeRedundancy)
{
- buildAssetInfo.CalculateShareBundleName(packRule, command.UniqueBundleName, command.PackageName, command.ShadersBundleName);
+ var command = collectResult.Command;
+ foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
+ {
+ buildAssetInfo.CalculateShareBundleName(sharePackRule, command.UniqueBundleName, command.PackageName, command.ShadersBundleName);
+ }
+ }
+ else
+ {
+ // 记录冗余资源
+ foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
+ {
+ if (buildAssetInfo.IsRedundancyAsset())
+ {
+ var redundancyInfo = new ReportRedundancyInfo();
+ redundancyInfo.AssetPath = buildAssetInfo.AssetPath;
+ redundancyInfo.AssetType = AssetDatabase.GetMainAssetTypeAtPath(buildAssetInfo.AssetPath).Name;
+ redundancyInfo.AssetGUID = AssetDatabase.AssetPathToGUID(buildAssetInfo.AssetPath);
+ redundancyInfo.FileSize = FileUtility.GetFileSize(buildAssetInfo.AssetPath);
+ redundancyInfo.Number = buildAssetInfo.GetReferenceBundleCount();
+ context.RedundancyInfos.Add(redundancyInfo);
+ }
+ }
}
// 9. 移除不参与构建的资源
diff --git a/Assets/YooAsset/Editor/AssetBundleReporter/AssetBundleReporterWindow.cs b/Assets/YooAsset/Editor/AssetBundleReporter/AssetBundleReporterWindow.cs
index 92d945a..f0a9db3 100644
--- a/Assets/YooAsset/Editor/AssetBundleReporter/AssetBundleReporterWindow.cs
+++ b/Assets/YooAsset/Editor/AssetBundleReporter/AssetBundleReporterWindow.cs
@@ -35,12 +35,18 @@ namespace YooAsset.Editor
/// 资源包视图
///
BundleView,
+
+ ///
+ /// 冗余资源试图
+ ///
+ Redundancy,
}
private ToolbarMenu _viewModeMenu;
private ReporterSummaryViewer _summaryViewer;
private ReporterAssetListViewer _assetListViewer;
private ReporterBundleListViewer _bundleListViewer;
+ private ReporterRedundancyListViewer _redundancyListViewer;
private EViewMode _viewMode;
private BuildReport _buildReport;
@@ -70,6 +76,7 @@ namespace YooAsset.Editor
_viewModeMenu.menu.AppendAction(EViewMode.Summary.ToString(), ViewModeMenuAction0, ViewModeMenuFun0);
_viewModeMenu.menu.AppendAction(EViewMode.AssetView.ToString(), ViewModeMenuAction1, ViewModeMenuFun1);
_viewModeMenu.menu.AppendAction(EViewMode.BundleView.ToString(), ViewModeMenuAction2, ViewModeMenuFun2);
+ _viewModeMenu.menu.AppendAction(EViewMode.Redundancy.ToString(), ViewModeMenuAction3, ViewModeMenuFun3);
// 搜索栏
var searchField = root.Q("SearchField");
@@ -87,6 +94,10 @@ namespace YooAsset.Editor
_bundleListViewer = new ReporterBundleListViewer();
_bundleListViewer.InitViewer();
+ // 加载试图
+ _redundancyListViewer = new ReporterRedundancyListViewer();
+ _redundancyListViewer.InitViewer();
+
// 显示视图
_viewMode = EViewMode.Summary;
_viewModeMenu.text = EViewMode.Summary.ToString();
@@ -111,9 +122,10 @@ namespace YooAsset.Editor
_reportFilePath = selectFilePath;
string jsonData = FileUtility.ReadAllText(_reportFilePath);
_buildReport = BuildReport.Deserialize(jsonData);
+ _summaryViewer.FillViewData(_buildReport);
_assetListViewer.FillViewData(_buildReport, _searchKeyWord);
_bundleListViewer.FillViewData(_buildReport, _reportFilePath, _searchKeyWord);
- _summaryViewer.FillViewData(_buildReport);
+ _redundancyListViewer.FillViewData(_buildReport, _searchKeyWord);
}
private void OnSearchKeyWordChange(ChangeEvent e)
{
@@ -134,6 +146,7 @@ namespace YooAsset.Editor
_summaryViewer.AttachParent(root);
_assetListViewer.DetachParent();
_bundleListViewer.DetachParent();
+ _redundancyListViewer.DetachParent();
}
}
private void ViewModeMenuAction1(DropdownMenuAction action)
@@ -146,6 +159,7 @@ namespace YooAsset.Editor
_summaryViewer.DetachParent();
_assetListViewer.AttachParent(root);
_bundleListViewer.DetachParent();
+ _redundancyListViewer.DetachParent();
}
}
private void ViewModeMenuAction2(DropdownMenuAction action)
@@ -158,6 +172,20 @@ namespace YooAsset.Editor
_summaryViewer.DetachParent();
_assetListViewer.DetachParent();
_bundleListViewer.AttachParent(root);
+ _redundancyListViewer.DetachParent();
+ }
+ }
+ private void ViewModeMenuAction3(DropdownMenuAction action)
+ {
+ if (_viewMode != EViewMode.Redundancy)
+ {
+ _viewMode = EViewMode.Redundancy;
+ VisualElement root = this.rootVisualElement;
+ _viewModeMenu.text = EViewMode.Redundancy.ToString();
+ _summaryViewer.DetachParent();
+ _assetListViewer.DetachParent();
+ _bundleListViewer.DetachParent();
+ _redundancyListViewer.AttachParent(root);
}
}
private DropdownMenuAction.Status ViewModeMenuFun0(DropdownMenuAction action)
@@ -181,6 +209,13 @@ namespace YooAsset.Editor
else
return DropdownMenuAction.Status.Normal;
}
+ private DropdownMenuAction.Status ViewModeMenuFun3(DropdownMenuAction action)
+ {
+ if (_viewMode == EViewMode.Redundancy)
+ return DropdownMenuAction.Status.Checked;
+ else
+ return DropdownMenuAction.Status.Normal;
+ }
}
}
#endif
\ No newline at end of file
diff --git a/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterRedundancyListViewer.cs b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterRedundancyListViewer.cs
new file mode 100644
index 0000000..685194c
--- /dev/null
+++ b/Assets/YooAsset/Editor/AssetBundleReporter/VisualViewers/ReporterRedundancyListViewer.cs
@@ -0,0 +1,317 @@
+#if UNITY_2019_4_OR_NEWER
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+using UnityEditor.UIElements;
+using UnityEngine.UIElements;
+
+namespace YooAsset.Editor
+{
+ internal class ReporterRedundancyListViewer
+ {
+ private enum ESortMode
+ {
+ AssetPath,
+ AssetType,
+ FileSize,
+ Number,
+ }
+
+ private VisualTreeAsset _visualAsset;
+ private TemplateContainer _root;
+
+ private ToolbarButton _topBar1;
+ private ToolbarButton _topBar2;
+ private ToolbarButton _topBar3;
+ private ToolbarButton _topBar4;
+ private ListView _assetListView;
+
+ private BuildReport _buildReport;
+ private string _searchKeyWord;
+ private ESortMode _sortMode = ESortMode.AssetPath;
+ private bool _descendingSort = false;
+
+
+ ///
+ /// 初始化页面
+ ///
+ public void InitViewer()
+ {
+ // 加载布局文件
+ _visualAsset = UxmlLoader.LoadWindowUXML();
+ if (_visualAsset == null)
+ return;
+
+ _root = _visualAsset.CloneTree();
+ _root.style.flexGrow = 1f;
+
+ // 顶部按钮栏
+ _topBar1 = _root.Q("TopBar1");
+ _topBar2 = _root.Q("TopBar2");
+ _topBar3 = _root.Q("TopBar3");
+ _topBar4 = _root.Q("TopBar4");
+ _topBar1.clicked += TopBar1_clicked;
+ _topBar2.clicked += TopBar2_clicked;
+ _topBar3.clicked += TopBar3_clicked;
+ _topBar4.clicked += TopBar4_clicked;
+
+ // 资源列表
+ _assetListView = _root.Q("TopListView");
+ _assetListView.makeItem = MakeAssetListViewItem;
+ _assetListView.bindItem = BindAssetListViewItem;
+ }
+
+ ///
+ /// 填充页面数据
+ ///
+ public void FillViewData(BuildReport buildReport, string searchKeyWord)
+ {
+ _buildReport = buildReport;
+ _searchKeyWord = searchKeyWord;
+ RefreshView();
+ }
+ private void RefreshView()
+ {
+ _assetListView.Clear();
+ _assetListView.ClearSelection();
+ _assetListView.itemsSource = FilterAndSortViewItems();
+ _assetListView.Rebuild();
+ RefreshSortingSymbol();
+ }
+ private List FilterAndSortViewItems()
+ {
+ List result = new List(_buildReport.RedundancyInfos.Count);
+
+ // 过滤列表
+ foreach (var redundancyInfo in _buildReport.RedundancyInfos)
+ {
+ if (string.IsNullOrEmpty(_searchKeyWord) == false)
+ {
+ if (redundancyInfo.AssetPath.Contains(_searchKeyWord) == false)
+ continue;
+ }
+ result.Add(redundancyInfo);
+ }
+
+ // 排序列表
+ if (_sortMode == ESortMode.AssetPath)
+ {
+ if (_descendingSort)
+ return result.OrderByDescending(a => a.AssetPath).ToList();
+ else
+ return result.OrderBy(a => a.AssetPath).ToList();
+ }
+ else if(_sortMode == ESortMode.AssetType)
+ {
+ if (_descendingSort)
+ return result.OrderByDescending(a => a.AssetType).ToList();
+ else
+ return result.OrderBy(a => a.AssetType).ToList();
+ }
+ else if (_sortMode == ESortMode.FileSize)
+ {
+ if (_descendingSort)
+ return result.OrderByDescending(a => a.FileSize).ToList();
+ else
+ return result.OrderBy(a => a.FileSize).ToList();
+ }
+ else if (_sortMode == ESortMode.Number)
+ {
+ if (_descendingSort)
+ return result.OrderByDescending(a => a.Number).ToList();
+ else
+ return result.OrderBy(a => a.Number).ToList();
+ }
+ else
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+ private void RefreshSortingSymbol()
+ {
+ _topBar1.text = $"Asset Path ({_assetListView.itemsSource.Count})";
+ _topBar2.text = "Asset Type";
+ _topBar3.text = "File Size";
+ _topBar4.text = "Redundancy Num";
+
+ if (_sortMode == ESortMode.AssetPath)
+ {
+ if (_descendingSort)
+ _topBar1.text = $"Asset Path ({_assetListView.itemsSource.Count}) ↓";
+ else
+ _topBar1.text = $"Asset Path ({_assetListView.itemsSource.Count}) ↑";
+ }
+ else if(_sortMode == ESortMode.AssetType)
+ {
+ if (_descendingSort)
+ _topBar2.text = "Asset Type ↓";
+ else
+ _topBar2.text = "Asset Type ↑";
+ }
+ else if (_sortMode == ESortMode.FileSize)
+ {
+ if (_descendingSort)
+ _topBar3.text = "File Size ↓";
+ else
+ _topBar3.text = "File Size ↑";
+ }
+ else if (_sortMode == ESortMode.Number)
+ {
+ if (_descendingSort)
+ _topBar4.text = "Redundancy Num ↓";
+ else
+ _topBar4.text = "Redundancy Num ↑";
+ }
+ else
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+
+ ///
+ /// 挂接到父类页面上
+ ///
+ public void AttachParent(VisualElement parent)
+ {
+ parent.Add(_root);
+ }
+
+ ///
+ /// 从父类页面脱离开
+ ///
+ public void DetachParent()
+ {
+ _root.RemoveFromHierarchy();
+ }
+
+
+ // 资源列表相关
+ private VisualElement MakeAssetListViewItem()
+ {
+ VisualElement element = new VisualElement();
+ element.style.flexDirection = FlexDirection.Row;
+
+ {
+ var label = new Label();
+ label.name = "Label1";
+ label.style.unityTextAlign = TextAnchor.MiddleLeft;
+ label.style.marginLeft = 3f;
+ label.style.flexGrow = 1f;
+ label.style.width = 280;
+ element.Add(label);
+ }
+
+ {
+ var label = new Label();
+ label.name = "Label2";
+ label.style.unityTextAlign = TextAnchor.MiddleLeft;
+ label.style.marginLeft = 3f;
+ label.style.flexGrow = 0;
+ label.style.width = 125;
+ element.Add(label);
+ }
+
+ {
+ var label = new Label();
+ label.name = "Label3";
+ label.style.unityTextAlign = TextAnchor.MiddleLeft;
+ label.style.marginLeft = 3f;
+ label.style.flexGrow = 0;
+ label.style.width = 125;
+ element.Add(label);
+ }
+
+ {
+ var label = new Label();
+ label.name = "Label4";
+ label.style.unityTextAlign = TextAnchor.MiddleLeft;
+ label.style.marginLeft = 3f;
+ label.style.flexGrow = 0;
+ label.style.width = 125;
+ element.Add(label);
+ }
+
+ return element;
+ }
+ private void BindAssetListViewItem(VisualElement element, int index)
+ {
+ var sourceData = _assetListView.itemsSource as List;
+ var redundancyInfo = sourceData[index];
+
+ // Asset Path
+ var label1 = element.Q