initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
|
@ -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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 850aa6537906d2342a70d728ad6e8245
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6356449d0e7fa7647972b14e67e3273b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 28a940f3bb234e34baec3af2b61b8d67
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b8b29c1ae0b68044bbce3aba8fc64eb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Add table
Add a link
Reference in a new issue