initial commit

This commit is contained in:
Jo 2025-01-07 02:06:59 +01:00
parent 6715289efe
commit 788c3389af
37645 changed files with 2526849 additions and 80 deletions

View file

@ -0,0 +1,545 @@
#if UNITY_2022_2_OR_NEWER
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.AddressableAssets.Build.Layout;
using UnityEditor.AddressableAssets.GUIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.AddressableAssets.BuildReportVisualizer
{
class DetailsContentView
{
protected VisualTreeAsset m_DetailsContentDrillableListItem;
protected List<DetailsListItem> m_ContentItems;
protected Label m_ActiveContentsName;
protected ListView m_ContentItemsListView;
BuildReportWindow m_Window;
protected VisualElement m_ContentsPane;
protected Image m_ActiveContentIcon;
VisualElement m_Toolbar;
ContextualMenuManipulator contextMenuManipulator;
const float m_ItemHeight = 24f;
RibbonButton m_RefToButton;
RibbonButton m_RefByButton;
Button m_BackButton;
protected Dictionary<VisualElement, List<Action>> m_ButtonCallBackTracker = new Dictionary<VisualElement, List<Action>>();
public DetailsContentView(VisualElement root, BuildReportWindow window)
{
m_Window = window;
m_ContentsPane = root.Q<VisualElement>(BuildReportUtility.DetailsContentsList);
m_ActiveContentsName = root.Q<Label>(BuildReportUtility.BreadcrumbToolbarName);
m_ActiveContentIcon = root.Q<Image>(BuildReportUtility.BreadcrumbToolbarIcon);
m_Toolbar = root.Q<VisualElement>(BuildReportUtility.BreadcrumbToolbar);
var stylesheetPath = BuildReportUtility.GetDetailsViewStylesheetPath();
m_Toolbar.styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(stylesheetPath));
m_ActiveContentsName.style.textOverflow = TextOverflow.Ellipsis;
m_ActiveContentsName.style.overflow = Overflow.Hidden;
m_ActiveContentsName.style.unityFontStyleAndWeight = FontStyle.Bold;
contextMenuManipulator = GenerateContextMenu();
m_ActiveContentsName.AddManipulator(contextMenuManipulator);
m_DetailsContentDrillableListItem = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(BuildReportUtility.DrillableListViewItemPath);
m_RefByButton = root.Q<RibbonButton>(BuildReportUtility.ReferencedByTab);
m_RefToButton = root.Q<RibbonButton>(BuildReportUtility.ReferencesToTab);
m_ContentItems = new List<DetailsListItem>();
m_ContentItemsListView = new ListView(m_ContentItems, m_ItemHeight, RefToMakeItem, RefToBindItem);
m_ContentItemsListView.showAlternatingRowBackgrounds = AlternatingRowBackground.All;
m_ContentItemsListView.style.marginLeft = new StyleLength(new Length(4f, LengthUnit.Pixel));
m_ContentItemsListView.visible = false;
m_BackButton = root.Q<Button>(BuildReportUtility.BreadcrumbToolbarBackButton);
BuildReportUtility.SetVisibility(m_BackButton, false);
m_BackButton.style.backgroundImage = new StyleBackground(BuildReportUtility.GetIcon(BuildReportUtility.GetBackIconPath()) as Texture2D);
m_BackButton.style.unityTextAlign = TextAnchor.MiddleCenter;
m_BackButton.clicked += () =>
{
DetailsStack.Pop();
};
m_ContentsPane.Add(m_ContentItemsListView);
DetailsStack.OnPop += (item) =>
{
DisplayContents(item);
RefreshBackButton();
};
DetailsStack.OnPush += (item) =>
{
RefreshBackButton();
};
}
public void DisplayContents(object item, DetailsViewTab tab)
{
RefreshBackButton();
DetailsContents contentsToDisplay = null;
if (item is DetailsContents)
contentsToDisplay = item as DetailsContents;
else if (DetailsUtility.IsBundle(item))
{
var bundle = DetailsUtility.GetBundle(item);
UpdateTabButtons(GetRefByCount(bundle), GetRefToCount(bundle));
contentsToDisplay = GetContents(bundle, tab);
}
else
{
var asset = DetailsUtility.GetAsset(item);
if (asset != null)
{
UpdateTabButtons(GetRefByCount(asset), GetRefToCount(asset));
contentsToDisplay = GetContents(asset, tab);
}
else
{
var otherAsset = DetailsUtility.GetOtherAssetData(item);
if (otherAsset != null)
{
UpdateTabButtons(GetRefByCount(otherAsset), GetRefToCount(otherAsset));
contentsToDisplay = GetContents(otherAsset, tab);
}
}
}
DisplayContents(contentsToDisplay);
}
public void ClearContents()
{
m_ContentItems.Clear();
m_ContentItemsListView.RefreshItems();
}
DetailsContents m_ActiveContents;
void DisplayContents(DetailsContents contents)
{
ClearContents();
m_ActiveContents = contents;
RefreshBackButton();
if (contents == null)
{
UpdateTabButtons(0,0);
m_ContentItemsListView.RefreshItems();
m_ContentItemsListView.visible = false;
m_ActiveContentsName.text = "";
m_ActiveContentIcon.image = null;
return;
}
m_ActiveContentsName.text = contents.Title;
m_ActiveContentIcon.image = BuildReportUtility.GetIcon(contents.AssetPath);
if (contents.AssetPath != BuildReportUtility.GetAssetBundleIconPath())
{
m_ActiveContentsName.tooltip = "Asset Path: " + contents.AssetPath;
m_ActiveContentsName.displayTooltipWhenElided = false;
}
else
{
m_ActiveContentsName.tooltip = null;
m_ActiveContentsName.displayTooltipWhenElided = true;
}
foreach (var item in contents.DrillableItems)
m_ContentItems.Add(item);
m_ContentItemsListView.RefreshItems();
m_ContentItemsListView.style.maxHeight = m_ContentItems.Count * m_ItemHeight;
if (!m_ContentItemsListView.visible)
m_ContentItemsListView.visible = true;
}
private ContextualMenuManipulator GenerateContextMenu()
{
var manip = new ContextualMenuManipulator((ContextualMenuPopulateEvent evt) =>
{
evt.menu.AppendAction("Search in this window", (e) =>
{
string newSearchValue = m_ActiveContentsName.text;
string isInBundleString = "(in this Bundle)";
if (newSearchValue.EndsWith(isInBundleString))
newSearchValue = newSearchValue.Substring(0, newSearchValue.Length - isInBundleString.Length - 1);
m_Window.m_ActiveContentView.m_SearchField.Q<TextField>().value = newSearchValue;
});
});
return manip;
}
private List<BuildLayout.ExplicitAsset> GetReferencingAssetsFromBundle(BuildLayout.Bundle referencingBundle, BuildLayout.Bundle bundle)
{
var referencingAssets = new List<BuildLayout.ExplicitAsset>();
foreach (var bd in referencingBundle.BundleDependencies)
{
if (bd.DependencyBundle == bundle)
{
foreach (var assetDep in bd.AssetDependencies)
referencingAssets.Add(assetDep.rootAsset);
return referencingAssets;
}
}
return referencingAssets;
}
DetailsContents GetContents(BuildLayout.Bundle bundle, DetailsViewTab tab)
{
DetailsContents value = new DetailsContents(bundle.Name, BuildReportUtility.GetAssetBundleIconPath());
switch(tab)
{
case DetailsViewTab.ReferencedBy:
foreach (var referencingBundle in bundle.DependentBundles)
{
var referencingAssetList = GetReferencingAssetsFromBundle(referencingBundle, bundle);
if (referencingAssetList.Count > 0)
{
value.DrillableItems.Add(new DetailsListItem(referencingBundle.Name, BuildReportUtility.GetAssetBundleIconPath(), () => ShowAssetsThatLinkToBundle(DetailsViewTab.ReferencedBy,
referencingBundle,
GetReferencingAssetsFromBundle(referencingBundle, bundle)), BuildReportUtility.GetForwardIconPath()));
}
else
{
value.DrillableItems.Add(new DetailsListItem(referencingBundle.Name, BuildReportUtility.GetAssetBundleIconPath(), null, null));
}
}
if (value.DrillableItems.Count == 0)
value.DrillableItems.Add(new DetailsListItem($"No AssetBundles have this listed as a dependency", BuildReportUtility.GetAssetBundleIconPath(), null, null));
break;
case DetailsViewTab.ReferencesTo:
foreach (var file in bundle.Files)
{
Dictionary<string, int> addressToIndexMap = new Dictionary<string, int>();
int index = 0;
foreach (var asset in file.Assets)
{
Action drillDownEvent = null;
if (asset.ExternallyReferencedAssets.Count > 0)
drillDownEvent = () => ShowReferencesToForAsset(value, asset, true);
DetailsListItem drillableItem = new DetailsListItem(asset.AddressableName, asset.AssetPath, drillDownEvent, drillDownEvent == null ? null : BuildReportUtility.GetForwardIconPath());
addressToIndexMap.Add(asset.AddressableName, index++);
value.DrillableItems.Add(drillableItem);
}
foreach (var implicitAsset in file.OtherAssets)
value.DrillableItems.Add(new DetailsListItem(implicitAsset.AssetPath,
implicitAsset.AssetPath,
() =>
{
List<int> referencingItems = new List<int>();
foreach(var refAsset in implicitAsset.ReferencingAssets)
referencingItems.Add(addressToIndexMap[refAsset.AddressableName]);
m_ContentItemsListView.SetSelection(referencingItems);
},BuildReportUtility.GetHelpIconPath(), FontStyle.Italic));
}
break;
}
return value;
}
void ShowReferencesByForAsset(DetailsContents value, BuildLayout.ExplicitAsset asset, bool shouldCallDisplayContents)
{
if (shouldCallDisplayContents)
value = new DetailsContents(asset.AddressableName, asset.AssetPath);
foreach (var refAsset in asset.ReferencingAssets)
{
if (refAsset.Bundle == asset.Bundle)
value.DrillableItems.Add(new DetailsListItem(refAsset.AddressableName, refAsset.AssetPath, null, null));
else
{
value.DrillableItems.Add(new DetailsListItem(refAsset.Bundle.Name, BuildReportUtility.GetAssetBundleIconPath(), () => ShowAssetsThatLinkToBundle(DetailsViewTab.ReferencedBy,
refAsset.Bundle,
GetAssetsThatLinkFromBundleMap(asset.Bundle, refAsset)[refAsset.Bundle]), BuildReportUtility.GetForwardIconPath()));
}
}
if (shouldCallDisplayContents)
{
DetailsStack.Push(m_ActiveContents);
DisplayContents(value);
}
}
void ShowReferencesToForAsset(DetailsContents value, BuildLayout.ExplicitAsset asset, bool shouldCallDisplayContents)
{
if (shouldCallDisplayContents)
value = new DetailsContents(asset.AddressableName, asset.AssetPath);
foreach (var internalAsset in asset.InternalReferencedExplicitAssets)
value.DrillableItems.Add(new DetailsListItem(internalAsset.AddressableName, internalAsset.AssetPath, null, null));
foreach (var externalAsset in asset.ExternallyReferencedAssets)
value.DrillableItems.Add(new DetailsListItem(externalAsset.Bundle.Name, BuildReportUtility.GetAssetBundleIconPath(), () => ShowAssetsThatLinkToBundle(
DetailsViewTab.ReferencesTo,
externalAsset.Bundle,
GetAssetsThatLinkToBundleMap(asset.Bundle, asset)[externalAsset.Bundle]), BuildReportUtility.GetForwardIconPath()));
foreach (var implicitAsset in asset.InternalReferencedOtherAssets)
value.DrillableItems.Add(new DetailsListItem(implicitAsset.AssetPath, implicitAsset.AssetPath, null, null, FontStyle.Italic));
if (shouldCallDisplayContents)
{
DetailsStack.Push(m_ActiveContents);
DisplayContents(value);
}
}
Dictionary<BuildLayout.Bundle, List<BuildLayout.ExplicitAsset>> GetAssetsThatLinkToBundleMap(BuildLayout.Bundle bundle, BuildLayout.ExplicitAsset asset)
{
Dictionary<BuildLayout.Bundle, List<BuildLayout.ExplicitAsset>> bundlesLinkedToAsset = new Dictionary<BuildLayout.Bundle, List<BuildLayout.ExplicitAsset>>();
foreach(var bDep in bundle.BundleDependencies)
{
foreach (var depAsset in bDep.AssetDependencies)
{
if (depAsset.rootAsset == asset)
{
var depBundle = depAsset.dependencyAsset.Bundle;
if (!bundlesLinkedToAsset.ContainsKey(depBundle))
bundlesLinkedToAsset[depBundle] = new List<BuildLayout.ExplicitAsset>();
bundlesLinkedToAsset[depBundle].Add(depAsset.dependencyAsset);
}
}
}
return bundlesLinkedToAsset;
}
Dictionary<BuildLayout.Bundle, List<BuildLayout.ExplicitAsset>> GetAssetsThatLinkFromBundleMap(BuildLayout.Bundle bundle, BuildLayout.ExplicitAsset asset)
{
Dictionary<BuildLayout.Bundle, List<BuildLayout.ExplicitAsset>> bundlesLinkedToAsset = new Dictionary<BuildLayout.Bundle, List<BuildLayout.ExplicitAsset>>();
//oof - this sucks, surely there's another way
foreach(var bDep in bundle.DependentBundles)
{
foreach (var depFile in bDep.Files)
{
foreach (var depAsset in depFile.Assets)
{
if (depAsset == asset)
{
var depBundle = depAsset.Bundle;
if (!bundlesLinkedToAsset.ContainsKey(depBundle))
bundlesLinkedToAsset[depBundle] = new List<BuildLayout.ExplicitAsset>();
bundlesLinkedToAsset[depBundle].Add(depAsset);
}
}
}
}
return bundlesLinkedToAsset;
}
void ShowAssetsThatLinkToBundle(DetailsViewTab tab, BuildLayout.Bundle bundle, List<BuildLayout.ExplicitAsset> linkedAssets)
{
DetailsContents dc = new DetailsContents(bundle.Name, BuildReportUtility.GetAssetBundleIconPath());
foreach (var asset in linkedAssets)
{
Action onDrillDown = null;
if (tab == DetailsViewTab.ReferencesTo && asset.ExternallyReferencedAssets.Count > 0)
onDrillDown = () => ShowReferencesToForAsset(dc, asset, true);
if (tab == DetailsViewTab.ReferencedBy && asset.ReferencingAssets.Count > 0)
onDrillDown = () => ShowReferencesByForAsset(dc, asset, true);
dc.DrillableItems.Add(new DetailsListItem(asset.AddressableName, asset.AssetPath, onDrillDown, onDrillDown == null ? null : BuildReportUtility.GetForwardIconPath()));
}
if (bundle.AssetCount - linkedAssets.Count > 0)
dc.DrillableItems.Add(new DetailsListItem($"({bundle.AssetCount - linkedAssets.Count}) other assets", null));
DetailsStack.Push(m_ActiveContents);
DisplayContents(dc);
}
DetailsContents GetContents(BuildLayout.ExplicitAsset asset, DetailsViewTab tab)
{
DetailsContents value = new DetailsContents(asset.AddressableName, asset.AssetPath);
switch (tab)
{
case DetailsViewTab.ReferencedBy:
ShowReferencesByForAsset(value, asset, false);
break;
case DetailsViewTab.ReferencesTo:
ShowReferencesToForAsset(value, asset, false);
break;
}
return value;
}
DetailsContents GetContents(BuildLayout.DataFromOtherAsset asset, DetailsViewTab tab)
{
DetailsContents value = new DetailsContents($"{asset.AssetPath} (in this Bundle)", asset.AssetPath);
switch(tab)
{
case DetailsViewTab.ReferencedBy:
foreach (var refAsset in asset.ReferencingAssets)
value.DrillableItems.Add(new DetailsListItem(refAsset.AddressableName, refAsset.AssetPath, null, null));
break;
case DetailsViewTab.ReferencesTo:
//Do nothing
break;
}
return value;
}
VisualElement RefToMakeItem()
{
var vta = m_DetailsContentDrillableListItem.Clone();
m_ButtonCallBackTracker.Add(vta, new List<Action>());
Button button = vta.Q<Button>(BuildReportUtility.DrillableListViewButton);
BuildReportUtility.SetVisibility(button, false);
return vta;
}
void RefToBindItem(VisualElement e, int i)
{
var drillDownEvent = m_ContentItems[i].DrillDownEvent;
Image icon = e.Q<Image>(BuildReportUtility.DrillableListViewItemIcon);
icon.image = null;
if (!string.IsNullOrEmpty(m_ContentItems[i].ImagePath) && BuildReportUtility.GetIcon(m_ContentItems[i].ImagePath) is Texture iconTexture && iconTexture != null)
{
icon.image = iconTexture;
icon.RemoveFromClassList(BuildReportUtility.TreeViewItemNoIcon);
}
else
{
icon.AddToClassList(BuildReportUtility.TreeViewItemNoIcon);
}
Button button = e.Q<Button>(BuildReportUtility.DrillableListViewButton);
var label = e.Q<Label>(BuildReportUtility.DrillableListViewItemName);
string buttonIconPath = m_ContentItems[i].ButtonImagePath;
if(!string.IsNullOrEmpty(buttonIconPath))
{
if (buttonIconPath == BuildReportUtility.GetHelpIconPath())
button.tooltip = "Selects the asset(s) that pulled this non-addressable asset into the bundle";
else
button.tooltip = null;
button.style.backgroundImage = new StyleBackground(BuildReportUtility.GetIcon(buttonIconPath) as Texture2D);
button.style.maxHeight = button.style.maxWidth = new Length(16f, LengthUnit.Pixel);
button.text = "";
label.style.minWidth = new Length(88f, LengthUnit.Percent);
}
label.text = m_ContentItems[i].Text;
if (m_ContentItems[i].ImagePath != BuildReportUtility.GetAssetBundleIconPath())
label.tooltip = "Asset Path: " + m_ContentItems[i].ImagePath;
label.style.unityFontStyleAndWeight = m_ContentItems[i].StyleForText;
if (m_ContentItems[i].CanUseContextMenu)
{
label.AddManipulator(new ContextualMenuManipulator((ContextualMenuPopulateEvent evt) =>
{
evt.menu.AppendAction("Search in this window", (e) =>
{
string newSearchValue = label.text;
m_Window.m_ActiveContentView.m_SearchField.Q<TextField>().value = newSearchValue;
});
}));
}
if (drillDownEvent == null)
{
label.style.maxWidth = label.style.width = new Length(88f, LengthUnit.Percent);
BuildReportUtility.SetVisibility(button, false);
}
else
{
label.style.maxWidth = label.style.width = new Length(64f, LengthUnit.Percent);
BuildReportUtility.SetVisibility(button, true);
foreach (var callback in m_ButtonCallBackTracker[e])
button.clicked -= callback;
m_ButtonCallBackTracker[e].Clear();
button.clicked += drillDownEvent;
m_ButtonCallBackTracker[e].Add(drillDownEvent);
}
}
void RefreshBackButton()
{
if (DetailsStack.Count > 0)
BuildReportUtility.SetVisibility(m_BackButton, true);
else
BuildReportUtility.SetVisibility(m_BackButton, false);
}
void UpdateTabButtons(int refBy, int refTo)
{
if (refBy == 0 && refTo == 0)
{
m_RefByButton.text = "Referenced By";
m_RefToButton.text = "References To";
}
else
{
m_RefByButton.text = $"Referenced By ({refBy})";
m_RefToButton.text = $"References To ({refTo})";
}
}
int GetRefByCount(BuildLayout.Bundle bundle)
{
return bundle.DependentBundles.Count;
}
int GetRefByCount(BuildLayout.ExplicitAsset asset)
{
return asset.ReferencingAssets.Count;
}
int GetRefByCount(BuildLayout.DataFromOtherAsset asset)
{
return asset.ReferencingAssets.Count;
}
int GetRefToCount(BuildLayout.Bundle bundle)
{
int total = 0;
foreach (var file in bundle.Files)
total += file.Assets.Count + file.OtherAssets.Count;
return total;
}
int GetRefToCount(BuildLayout.ExplicitAsset asset)
{
return asset.InternalReferencedExplicitAssets.Count + asset.ExternallyReferencedAssets.Count + asset.InternalReferencedOtherAssets.Count;
}
int GetRefToCount(BuildLayout.DataFromOtherAsset asset)
{
return 0;
}
}
}
#endif

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 850aa6537906d2342a70d728ad6e8245
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,29 @@
#if UNITY_2022_2_OR_NEWER
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.AddressableAssets.BuildReportVisualizer
{
internal class DetailsContents
{
public List<DetailsListItem> DrillableItems;
public string Title;
public string AssetPath;
public DetailsContents(string title, string assetPath)
{
Title = title;
AssetPath = assetPath;
DrillableItems = new List<DetailsListItem>();
}
public DetailsContents(string title, string assetPath, List<DetailsListItem> items)
{
Title = title;
AssetPath = assetPath;
DrillableItems = items;
}
}
}
#endif

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6356449d0e7fa7647972b14e67e3273b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,187 @@
#if UNITY_2022_2_OR_NEWER
using System.Collections;
using System.Collections.Generic;
using UnityEditor.AddressableAssets.Build.Layout;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using static UnityEditor.AddressableAssets.BuildReportVisualizer.BuildReportWindow;
namespace UnityEditor.AddressableAssets.BuildReportVisualizer
{
class DetailsSummaryView
{
BuildReportWindow m_Window;
protected VisualElement m_DetailsSummary;
VisualTreeAsset m_DetailsPanelSummaryNavigableItem;
VisualTreeAsset m_DetailsPanelSummaryNavigableBundle;
internal DetailsSummaryView(VisualElement root, BuildReportWindow window)
{
m_Window = window;
m_DetailsPanelSummaryNavigableItem = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(BuildReportUtility.DetailsPanelSummaryNavigableItem);
m_DetailsPanelSummaryNavigableBundle = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(BuildReportUtility.DetailsPanelSummaryNavigableBundle);
m_DetailsSummary = root.Q<VisualElement>(BuildReportUtility.DetailsSummaryPane);
m_DetailsSummary.style.paddingLeft =
m_DetailsSummary.style.paddingRight = new StyleLength(new Length(15f, LengthUnit.Pixel));
}
public void ClearSummary()
{
m_DetailsSummary.Clear();
}
public void UpdateSummary(object item)
{
ClearSummary();
if (DetailsUtility.IsBundle(item))
DisplayBundleSummary(DetailsUtility.GetBundle(item));
else
{
var asset = DetailsUtility.GetAsset(item);
if (asset != null)
DisplayExplicitAssetSummary(new BundlesViewBuildReportAsset(asset));
else
{
var otherAsset = DetailsUtility.GetOtherAssetData(item);
if (otherAsset != null)
DisplayDataFromOtherAssetSummary(new BundlesViewBuildReportAsset(otherAsset));
}
}
}
void DisplayBundleSummary(BuildLayout.Bundle bundle)
{
if (bundle == null)
return;
DetailsSummaryBuilder builder = new DetailsSummaryBuilder()
.With(BuildReportUtility.GetIcon(BuildReportUtility.GetAssetBundleIconPath()), bundle.Name)
.With("Uncompressed", $"{ BuildReportUtility.GetDenominatedBytesString(bundle.UncompressedFileSize)}")
.With("Bundle fizesize", $"{BuildReportUtility.GetDenominatedBytesString(bundle.FileSize)}")
.With("Total size (+ refs)", $"{BuildReportUtility.GetDenominatedBytesString(bundle.FileSize + bundle.DependencyFileSize + bundle.ExpandedDependencyFileSize)}")
.With("Group", bundle.Group.Name)
.With("Load Path", $"{bundle.LoadPath}");
m_DetailsSummary.Add(builder.Build());
m_DetailsSummary.Add(CreateButtonRow(
BuildReportUtility.CreateButton("Search in this view", () =>
{
string newSearchValue = bundle.Name;
m_Window.m_ActiveContentView.m_SearchField.Q<TextField>().value = newSearchValue;
}),
BuildReportUtility.CreateButton("Select in Group", () =>
{
m_Window.NavigateToView(ContentViewType.GroupsView);
m_Window.SelectItemInView(BuildReportUtility.ComputeDataHash(bundle.Group.Name, bundle.Name), true);
})));
}
public void DisplayExplicitAssetSummary(IAddressablesBuildReportAsset reportAsset)
{
DetailsSummaryBuilder builder = new DetailsSummaryBuilder()
.With(BuildReportUtility.GetIcon(reportAsset.ExplicitAsset.AssetPath), reportAsset.ExplicitAsset.AddressableName)
.With("Asset Path", reportAsset.ExplicitAsset.AssetPath)
.With("Uncompressed", $"{BuildReportUtility.GetDenominatedBytesString(reportAsset.ExplicitAsset.File.UncompressedSize)}")
.With("Total Size (+ refs)", $"{BuildReportUtility.GetDenominatedBytesString(reportAsset.SizeWDependencies)}");
if (reportAsset.Bundles != null)
{
foreach (BuildLayout.Bundle bundle in reportAsset.Bundles)
{
builder.With("Bundle", bundle.Name)
.With("Group", bundle.Group.Name)
.With("Labels", string.Join(", ", reportAsset.ExplicitAsset.Labels))
.With("Load Path", bundle.LoadPath);
}
}
m_DetailsSummary.Add(builder.Build());
m_DetailsSummary.Add(CreateButtonRow(
BuildReportUtility.CreateButton("Select in Editor", () =>
{
Selection.activeObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(reportAsset.ExplicitAsset.AssetPath);
}),
BuildReportUtility.CreateButton("Select in Group", () =>
{
m_Window.NavigateToView(ContentViewType.GroupsView);
m_Window.SelectItemInView(BuildReportUtility.ComputeDataHash(reportAsset.ExplicitAsset.AddressableName));
}),
BuildReportUtility.CreateButton("Search in this view", () =>
{
string newSearchValue = reportAsset.ExplicitAsset.AddressableName;
m_Window.m_ActiveContentView.m_SearchField.Q<TextField>().value = newSearchValue;
})));
m_DetailsSummary.Add(CreateButtonRow(BuildReportUtility.CreateButton("Select in Bundle", () =>
{
m_Window.NavigateToView(ContentViewType.BundleView);
m_Window.SelectItemInView(BuildReportUtility.ComputeDataHash(reportAsset.ExplicitAsset.Bundle.Name, reportAsset.ExplicitAsset.AddressableName));
})));
}
public void DisplayDataFromOtherAssetSummary(IAddressablesBuildReportAsset reportAsset)
{
DetailsSummaryBuilder builder = new DetailsSummaryBuilder()
.With(BuildReportUtility.GetIcon(reportAsset.DataFromOtherAsset.AssetPath), reportAsset.DataFromOtherAsset.AssetPath)
.With("Uncompressed", $"{BuildReportUtility.GetDenominatedBytesString(reportAsset.DataFromOtherAsset.File.UncompressedSize)}")
.With("Total Size (+ refs)", $"{BuildReportUtility.GetDenominatedBytesString(reportAsset.SizeWDependencies)}")
.With("Included in Bundle Count", reportAsset.Bundles.Count.ToString());
if (reportAsset.Bundles.Count > 1)
builder.With("Total size of all duplications", $"{BuildReportUtility.GetDenominatedBytesString(reportAsset.DataFromOtherAsset.SerializedSize * (ulong)reportAsset.Bundles.Count) }");
m_DetailsSummary.Add(builder.Build());
m_DetailsSummary.Add(CreateButtonRow(
BuildReportUtility.CreateButton("Search in this view", () =>
{
string newSearchValue = reportAsset.DataFromOtherAsset.AssetPath;
m_Window.m_ActiveContentView.m_SearchField.Q<TextField>().value = newSearchValue;
}),
BuildReportUtility.CreateButton("Select in Editor", () =>
{
Selection.activeObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(reportAsset.DataFromOtherAsset.AssetPath);
})));
m_DetailsSummary.Add(CreateHelpTextBox("This asset was pulled into the AssetBundle because one or more Addressable assets have references to it."));
}
VisualElement CreateButtonRow(params Button[] buttons)
{
VisualElement container = new VisualElement();
container.style.flexDirection = FlexDirection.Row;
container.style.marginTop = new StyleLength(new Length(18f, LengthUnit.Pixel));
foreach (var button in buttons)
container.Add(button);
return container;
}
VisualElement CreateHelpTextBox(string helpText)
{
Foldout foldout = new Foldout();
foldout.style.marginTop = new Length(10f, LengthUnit.Pixel);
foldout.style.marginBottom = new Length(25f, LengthUnit.Pixel);
foldout.style.height = new Length(20f, LengthUnit.Pixel);
foldout.style.flexDirection = FlexDirection.Column;
foldout.text = "Help";
VisualElement helpElement = new VisualElement();
foldout.Add(helpElement);
Label label = new Label();
helpElement.Add(label);
label.text = helpText;
label.style.paddingTop = new Length(25, LengthUnit.Pixel);
label.style.width = new Length(100, LengthUnit.Percent);
label.style.maxWidth = new Length(100, LengthUnit.Percent);
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.whiteSpace = WhiteSpace.Normal;
return foldout;
}
}
}
#endif

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 28a940f3bb234e34baec3af2b61b8d67
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,50 @@
#if UNITY_2022_2_OR_NEWER
using System.Collections;
using System.Collections.Generic;
using UnityEditor.AddressableAssets.Build.Layout;
using UnityEngine;
namespace UnityEditor.AddressableAssets.BuildReportVisualizer
{
internal static class DetailsUtility
{
public static BuildLayout.ExplicitAsset GetAsset(object item)
{
if (item is IAddressablesBuildReportAsset)
return (item as IAddressablesBuildReportAsset).ExplicitAsset;
else if (item is BuildLayout.ExplicitAsset)
return item as BuildLayout.ExplicitAsset;
return null;
}
public static BuildLayout.DataFromOtherAsset GetOtherAssetData(object item)
{
if (item is IAddressablesBuildReportAsset)
return (item as IAddressablesBuildReportAsset).DataFromOtherAsset;
else if (item is BuildLayout.DataFromOtherAsset)
return item as BuildLayout.DataFromOtherAsset;
return null;
}
public static bool IsBundle(object item)
{
if (item is IAddressablesBuildReportBundle || item is BuildLayout.Bundle)
return true;
return false;
}
public static BuildLayout.Bundle GetBundle(object item)
{
BuildLayout.Bundle bundle = null;
if (item is IAddressablesBuildReportBundle)
bundle = (item as IAddressablesBuildReportBundle).Bundle;
else if (item is BuildLayout.Bundle)
bundle = item as BuildLayout.Bundle;
return bundle;
}
}
}
#endif

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b8b29c1ae0b68044bbce3aba8fc64eb8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: