From 8fbbb7afc534be74a89db916b6c38651da147284 Mon Sep 17 00:00:00 2001
From: Unity Technologies <@unity>
Date: Mon, 26 Jul 2021 00:00:00 +0000
Subject: [PATCH] com.unity.addressables@1.18.15 ## [1.18.15] - 2021-07-26 -
Improved Addressables inspector for Assets. - Fixed issue where the hosting
window would use an exceptionally high (8-20%) amount of CPU while open with
a hosting service created - Added update on profile change, changed to remove
preceding slashes and change all to forward slash for hosting service - Added
documentation explaining why we are unable to support WaitForCompletion (sync
Addressables) on WebGL
---
CHANGELOG.md | 6 +
Documentation~/SynchronousAddressables.md | 7 +-
.../Build/AddressablesPlayerBuildProcessor.cs | 2 +
Editor/Build/MonoScriptBundleNaming.cs | 15 ++
...vertUnchangedAssetsToPreviousAssetState.cs | 23 +-
Editor/Build/ShaderBundleNaming.cs | 12 +
.../AddressableAssetsSettingsGroupEditor.cs | 17 +-
Editor/GUI/AssetInspectorGUI.cs | 255 +++++++++++++-----
.../GUI/HostingServicesProfileVarsTreeView.cs | 5 +
Editor/GUI/HostingServicesWindow.cs | 55 ++--
.../HostingServices/HostingServicesManager.cs | 15 ++
Editor/HostingServices/HttpHostingService.cs | 7 +-
Editor/Settings/AddressableAssetEntry.cs | 23 ++
Editor/Settings/AddressableAssetGroup.cs | 4 +-
Editor/Settings/AddressableAssetSettings.cs | 6 +-
Editor/Settings/AddressableAssetUtility.cs | 18 +-
Runtime/Addressables.cs | 6 +-
Runtime/AssetReference.cs | 2 +-
.../Initialization/PackedPlayModeBuildLogs.cs | 3 +
.../ResourceLocators/ResourceLocationData.cs | 6 +-
.../AsyncOperations/AsyncOperationBase.cs | 5 +-
.../AsyncOperations/ProviderOperation.cs | 3 +
.../Util/OperationCacheKeys.cs | 16 +-
.../AddressableAssetFolderSubfolderTests.cs | 2 +-
Tests/Editor/AddressableAssetSettingsTests.cs | 32 +--
Tests/Editor/AddressableAssetTestBase.cs | 54 ++--
Tests/Editor/AddressableAssetUtilityTests.cs | 89 +++++-
Tests/Editor/AddressableAssetsWindowTests.cs | 19 ++
Tests/Editor/Build/BuildScriptPackedTests.cs | 4 +-
Tests/Editor/Build/BuildScriptTests.cs | 12 +-
Tests/Editor/ContentUpdateTests.cs | 10 +
.../HostingServicesWindowUtilitiesTests.cs | 99 +++++++
...ostingServicesWindowUtilitiesTests.cs.meta | 11 +
.../ResourceManager/OperationsCacheTests.cs | 42 +++
ValidationExceptions.json | 2 +-
package.json | 6 +-
36 files changed, 692 insertions(+), 201 deletions(-)
create mode 100644 Tests/Editor/HostingServices/HostingServicesWindowUtilitiesTests.cs
create mode 100644 Tests/Editor/HostingServices/HostingServicesWindowUtilitiesTests.cs.meta
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c0d1a529..38aeb4f4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,12 @@ All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## [1.18.15] - 2021-07-26
+- Improved Addressables inspector for Assets.
+- Fixed issue where the hosting window would use an exceptionally high (8-20%) amount of CPU while open with a hosting service created
+- Added update on profile change, changed to remove preceding slashes and change all to forward slash for hosting service
+- Added documentation explaining why we are unable to support WaitForCompletion (sync Addressables) on WebGL
+
## [1.18.13] - 2021-07-13
- Fixed issue where Addressables would not use a custom Asset Bundle Provider if the default group was empty
- InvalidKeyExceptions are now correctly thrown as InvalidKeyExceptions, as opposed to before, where they were thrown as System.Exceptions. Please note that this may break any checks that rely on InvalidKeyExceptions being thrown as System.Exception
diff --git a/Documentation~/SynchronousAddressables.md b/Documentation~/SynchronousAddressables.md
index 8bdad8dd..45fcf7c5 100644
--- a/Documentation~/SynchronousAddressables.md
+++ b/Documentation~/SynchronousAddressables.md
@@ -34,4 +34,9 @@ void Start()
### Synchronous Addressables with Custom Operations
Addressables supports custom `AsyncOperations` which support unique implementations of `InvokeWaitForCompletion`. This overridable method is what you'll use to implement custom synchronous operations.
-Custom operations work with `ChainOperations` and `GroupsOperations`. If you require chained operations to be completed synchronously, ensure that your custom operations implement `InvokeWaitForCompletion` and create a `ChainOperation` using your custom operations. Similarly, `GroupOperations` are well suited to ensure a collection of `AsyncOperations`, including custom operations, complete together. Both `ChainOperation` and `GroupOperation` have their own implementations of `InvokeWaitForCompletion` that relies on the `InvokeWaitForCompletion` implementations of the operations they depend on.
\ No newline at end of file
+Custom operations work with `ChainOperations` and `GroupsOperations`. If you require chained operations to be completed synchronously, ensure that your custom operations implement `InvokeWaitForCompletion` and create a `ChainOperation` using your custom operations. Similarly, `GroupOperations` are well suited to ensure a collection of `AsyncOperations`, including custom operations, complete together. Both `ChainOperation` and `GroupOperation` have their own implementations of `InvokeWaitForCompletion` that relies on the `InvokeWaitForCompletion` implementations of the operations they depend on.
+
+### WebGL
+WebGL does not support `WaitForCompletion`. On WebGL, all files are loaded using a web request. On other platforms, a web request gets started on a background thread and the main thread spins in a tight loop while waiting for the web request to finish. This is how Addressables does it for `WaitForCompletion` when a web request is used.
+
+Since WebGL is single-threaded, the tight loop blocks the web request and the operation is never allowed to finish. If a web request finishes the same frame it was created, then `WaitForCompletion` wouldn't have any issue. However, we cannot guarantee this to be the case, and likely it isn't the case for most instances.
\ No newline at end of file
diff --git a/Editor/Build/AddressablesPlayerBuildProcessor.cs b/Editor/Build/AddressablesPlayerBuildProcessor.cs
index c3312e33..1a57c9c9 100644
--- a/Editor/Build/AddressablesPlayerBuildProcessor.cs
+++ b/Editor/Build/AddressablesPlayerBuildProcessor.cs
@@ -21,6 +21,7 @@ public int callbackOrder
///
/// Restores temporary data created as part of a build.
///
+ /// Stores temporary player build data.
public void OnPostprocessBuild(BuildReport report)
{
CleanTemporaryPlayerBuildData();
@@ -39,6 +40,7 @@ internal static void CleanTemporaryPlayerBuildData()
///
/// Initializes temporary build data.
///
+ /// Contains build data information.
public void OnPreprocessBuild(BuildReport report)
{
CopyTemporaryPlayerBuildData();
diff --git a/Editor/Build/MonoScriptBundleNaming.cs b/Editor/Build/MonoScriptBundleNaming.cs
index 41781ab1..3671f6e8 100644
--- a/Editor/Build/MonoScriptBundleNaming.cs
+++ b/Editor/Build/MonoScriptBundleNaming.cs
@@ -1,10 +1,25 @@
namespace UnityEditor.AddressableAssets.Build
{
+ ///
+ /// Naming conventions for the monoscript bundle name prefix.
+ ///
public enum MonoScriptBundleNaming
{
+ ///
+ /// No special prefix will be added to the monscript bundle name.
+ ///
Disabled,
+ ///
+ /// Set the monoscript bundle name prefix to the hash of the project name.
+ ///
ProjectName,
+ ///
+ /// Set the monoscript bundle name prefix to the guid of the default group.
+ ///
DefaultGroupGuid,
+ ///
+ /// Set the monoscript bundle name prefix to the user specified value.
+ ///
Custom
}
}
diff --git a/Editor/Build/RevertUnchangedAssetsToPreviousAssetState.cs b/Editor/Build/RevertUnchangedAssetsToPreviousAssetState.cs
index 1fc872ec..f7d9af91 100644
--- a/Editor/Build/RevertUnchangedAssetsToPreviousAssetState.cs
+++ b/Editor/Build/RevertUnchangedAssetsToPreviousAssetState.cs
@@ -13,6 +13,7 @@
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.ResourceProviders;
+using UnityEngine.ResourceManagement.Util;
using static UnityEditor.AddressableAssets.Build.ContentUpdateScript;
///
@@ -31,7 +32,7 @@ internal struct AssetEntryRevertOperation
}
///
- /// Reverts asset entries to their previous state if not modified by the new build.
+ /// Reverts asset entries to their previous state if not modified by the new build.
///
/// The new build data.
/// The cached build data.
@@ -109,8 +110,7 @@ internal static List DetermineRequiredAssetEntryUpdat
continue;
}
- string previousBundlePath = previousAssetState.bundleFileId?.Replace(loadPath, buildPath);
-
+ string previousBundlePath = BundleIdToBuildPath(previousAssetState.bundleFileId, loadPath, buildPath);
if (!File.Exists(previousBundlePath))
{
//Logging this as a warning because users may choose to delete their bundles on disk which will trigger this state.
@@ -119,7 +119,7 @@ internal static List DetermineRequiredAssetEntryUpdat
$"\"Use Existing Build (requires built groups)\" will fail.");
}
- string builtBundlePath = contentUpdateContext.BundleToInternalBundleIdMap[fullInternalBundleName].Replace(loadPath, buildPath);
+ string builtBundlePath = BundleIdToBuildPath(contentUpdateContext.BundleToInternalBundleIdMap[fullInternalBundleName], loadPath, buildPath);
AssetEntryRevertOperation operation = new AssetEntryRevertOperation()
{
@@ -134,10 +134,19 @@ internal static List DetermineRequiredAssetEntryUpdat
}
return operations;
}
-
+
+ internal static string BundleIdToBuildPath(string bundleId, string rootLoadPath, string rootBuildPath)
+ {
+ if (bundleId == null)
+ return null;
+ bool replaceBackSlashes = rootLoadPath.Contains('/') && !ResourceManagerConfig.ShouldPathUseWebRequest(rootLoadPath);
+ string path = replaceBackSlashes ? bundleId.Replace('\\', '/') : bundleId;
+ return path.Replace(rootLoadPath, rootBuildPath);
+ }
+
private static bool IsPreviouslyRevertedDependency(string bundleFileId, ContentUpdateContext contentUpdateContext)
{
- foreach(CachedAssetState state in contentUpdateContext.PreviousAssetStateCarryOver)
+ foreach (CachedAssetState state in contentUpdateContext.PreviousAssetStateCarryOver)
{
if (state.bundleFileId == bundleFileId)
return true;
@@ -155,7 +164,7 @@ internal static void ApplyAssetEntryUpdates(
{
//Check that we can replace the entry in the file registry
//before continuing. Past this point destructive actions are taken.
- if (contentUpdateContext.Registry.ReplaceBundleEntry(Path.GetFileNameWithoutExtension(operation.PreviousBuildPath), operation.PreviousAssetState.bundleFileId) ||
+ if (contentUpdateContext.Registry.ReplaceBundleEntry(Path.GetFileNameWithoutExtension(operation.PreviousBuildPath), operation.PreviousAssetState.bundleFileId) ||
IsPreviouslyRevertedDependency(operation.PreviousAssetState.bundleFileId, contentUpdateContext))
{
File.Delete(operation.CurrentBuildPath);
diff --git a/Editor/Build/ShaderBundleNaming.cs b/Editor/Build/ShaderBundleNaming.cs
index 042c5c79..8be1f91f 100644
--- a/Editor/Build/ShaderBundleNaming.cs
+++ b/Editor/Build/ShaderBundleNaming.cs
@@ -4,10 +4,22 @@
namespace UnityEditor.AddressableAssets.Build
{
+ ///
+ /// Naming conventions for the built-in shader bundle name prefix.
+ ///
public enum ShaderBundleNaming
{
+ ///
+ /// Set the built-in shader bundle name prefix to the hash of the project name.
+ ///
ProjectName,
+ ///
+ /// Set the built-in shader bundle name prefix to the guid of the default group.
+ ///
DefaultGroupGuid,
+ ///
+ /// Set the built-in shader bundle name prefix to the user specified value.
+ ///
Custom
}
}
diff --git a/Editor/GUI/AddressableAssetsSettingsGroupEditor.cs b/Editor/GUI/AddressableAssetsSettingsGroupEditor.cs
index ea7271a7..eab07e61 100644
--- a/Editor/GUI/AddressableAssetsSettingsGroupEditor.cs
+++ b/Editor/GUI/AddressableAssetsSettingsGroupEditor.cs
@@ -74,7 +74,22 @@ public void SelectEntries(IList entries)
while (items.Count > 0)
{
var i = items.Pop();
- if (!i.IsGroup && entries.Contains(i.entry))
+
+ bool contains = false;
+ if (i.entry != null)
+ {
+ foreach (AddressableAssetEntry entry in entries)
+ {
+ // class instances can be different but refer to the same entry, use guid
+ if (entry.guid == i.entry.guid && i.entry.TargetAsset == entry.TargetAsset)
+ {
+ contains = true;
+ break;
+ }
+ }
+ }
+
+ if (!i.IsGroup && contains)
{
selectedIDs.Add(i.id);
}
diff --git a/Editor/GUI/AssetInspectorGUI.cs b/Editor/GUI/AssetInspectorGUI.cs
index 1e5f5e66..10255687 100644
--- a/Editor/GUI/AssetInspectorGUI.cs
+++ b/Editor/GUI/AssetInspectorGUI.cs
@@ -11,7 +11,7 @@ namespace UnityEditor.AddressableAssets.GUI
using Object = UnityEngine.Object;
[InitializeOnLoad]
- static class AddressableAssetInspectorGUI
+ internal static class AddressableAssetInspectorGUI
{
static GUIStyle s_ToggleMixed;
static GUIContent s_AddressableAssetToggleText;
@@ -86,135 +86,244 @@ static void SetAaEntry(AddressableAssetSettings aaSettings, List tar
static void OnPostHeaderGUI(Editor editor)
{
var aaSettings = AddressableAssetSettingsDefaultObject.Settings;
- AddressableAssetEntry entry = null;
if (editor.targets.Length > 0)
{
- int addressableCount = 0;
- bool foundValidAsset = false;
- bool foundAssetGroup = false;
- var targetInfos = new List();
foreach (var t in editor.targets)
{
- foundAssetGroup |= t is AddressableAssetGroup;
- foundAssetGroup |= t is AddressableAssetGroupSchema;
- if (AddressableAssetUtility.GetPathAndGUIDFromTarget(t, out var path, out var guid, out var mainAssetType))
+ if (t is AddressableAssetGroup || t is AddressableAssetGroupSchema)
{
- // Is asset
- if (!BuildUtility.IsEditorAssembly(mainAssetType.Assembly))
- {
- foundValidAsset = true;
- var info = new TargetInfo(){Guid = guid, Path = path, MainAssetType = mainAssetType};
+ GUILayout.BeginHorizontal();
+ GUILayout.Label("Profile: " + AddressableAssetSettingsDefaultObject.GetSettings(true).profileSettings.
+ GetProfileName(AddressableAssetSettingsDefaultObject.GetSettings(true).activeProfileId));
- if (aaSettings != null)
- {
- entry = aaSettings.FindAssetEntry(guid);
- if (entry != null && !entry.IsSubAsset)
- {
- addressableCount++;
- info.Entry = entry;
- }
- }
- targetInfos.Add(info);
+ GUILayout.FlexibleSpace();
+ if (GUILayout.Button("System Settings", "MiniButton"))
+ {
+ EditorGUIUtility.PingObject(AddressableAssetSettingsDefaultObject.Settings);
+ Selection.activeObject = AddressableAssetSettingsDefaultObject.Settings;
}
+ GUILayout.EndHorizontal();
+ return;
}
}
+
+ List targetInfos = GatherTargetInfos(editor.targets, aaSettings);
+ if (targetInfos.Count == 0)
+ return;
- if (foundAssetGroup)
+ bool targetHasAddressableSubObject = false;
+ int mainAssetsAddressable = 0;
+ int subAssetsAddressable = 0;
+ foreach (TargetInfo info in targetInfos)
{
- GUILayout.BeginHorizontal();
- GUILayout.Label("Profile: " + AddressableAssetSettingsDefaultObject.GetSettings(true).profileSettings.
- GetProfileName(AddressableAssetSettingsDefaultObject.GetSettings(true).activeProfileId));
-
- GUILayout.FlexibleSpace();
- if (GUILayout.Button("System Settings", "MiniButton"))
- {
- EditorGUIUtility.PingObject(AddressableAssetSettingsDefaultObject.Settings);
- Selection.activeObject = AddressableAssetSettingsDefaultObject.Settings;
- }
- GUILayout.EndHorizontal();
+ if (info.MainAssetEntry == null)
+ continue;
+ if (info.MainAssetEntry.IsSubAsset)
+ subAssetsAddressable++;
+ else
+ mainAssetsAddressable++;
+ if (!info.IsMainAsset)
+ targetHasAddressableSubObject = true;
}
-
- if (!foundValidAsset)
- return;
// Overrides a DisabledScope in the EditorElement.cs that disables GUI drawn in the header when the asset cannot be edited.
bool prevEnabledState = UnityEngine.GUI.enabled;
- UnityEngine.GUI.enabled = true;
-
- if (addressableCount == 0)
+ if (targetHasAddressableSubObject)
+ UnityEngine.GUI.enabled = false;
+ else
+ {
+ UnityEngine.GUI.enabled = true;
+ foreach (var info in targetInfos)
+ {
+ if (!info.IsMainAsset)
+ {
+ UnityEngine.GUI.enabled = false;
+ break;
+ }
+ }
+ }
+
+ int totalAddressableCount = mainAssetsAddressable + subAssetsAddressable;
+ if (totalAddressableCount == 0) // nothing is addressable
{
if (GUILayout.Toggle(false, s_AddressableAssetToggleText, GUILayout.ExpandWidth(false)))
SetAaEntry(AddressableAssetSettingsDefaultObject.GetSettings(true), targetInfos, true);
}
- else if (addressableCount == editor.targets.Length)
+ else if (totalAddressableCount == editor.targets.Length) // everything is addressable
{
+ var entryInfo = targetInfos[targetInfos.Count - 1];
+ if (entryInfo == null || entryInfo.MainAssetEntry == null)
+ throw new NullReferenceException("EntryInfo incorrect for Addressables content.");
+
GUILayout.BeginHorizontal();
- if (!GUILayout.Toggle(true, s_AddressableAssetToggleText, GUILayout.ExpandWidth(false)))
+
+ if (mainAssetsAddressable > 0 && subAssetsAddressable > 0)
{
- SetAaEntry(aaSettings, targetInfos, false);
- UnityEngine.GUI.enabled = prevEnabledState;
- GUIUtility.ExitGUI();
+ if (s_ToggleMixed == null)
+ s_ToggleMixed = new GUIStyle("ToggleMixed");
+ if (GUILayout.Toggle(false, s_AddressableAssetToggleText, s_ToggleMixed, GUILayout.ExpandWidth(false)))
+ SetAaEntry(aaSettings, targetInfos, true);
}
+ else if (mainAssetsAddressable > 0)
+ {
+ if (!GUILayout.Toggle(true, s_AddressableAssetToggleText, GUILayout.ExpandWidth(false)))
+ {
+ SetAaEntry(aaSettings, targetInfos, false);
+ UnityEngine.GUI.enabled = prevEnabledState;
+ GUIUtility.ExitGUI();
+ }
+ }
+ else if (GUILayout.Toggle(false, s_AddressableAssetToggleText, GUILayout.ExpandWidth(false)))
+ SetAaEntry(aaSettings, targetInfos, true);
- if (editor.targets.Length == 1 && entry != null)
+ if (editor.targets.Length == 1)
{
- string newAddress = EditorGUILayout.DelayedTextField(entry.address, GUILayout.ExpandWidth(true));
- if (newAddress != entry.address)
+ if (!entryInfo.IsMainAsset || entryInfo.MainAssetEntry.IsSubAsset)
{
- if (newAddress.Contains("[") && newAddress.Contains("]"))
- Debug.LogErrorFormat("Rename of address '{0}' cannot contain '[ ]'.", entry.address);
- else
+ bool preAddressPrevEnabledState = UnityEngine.GUI.enabled;
+ UnityEngine.GUI.enabled = false;
+ string address = entryInfo.Address + (entryInfo.IsMainAsset ? "" : $"[{entryInfo.TargetObject.name}]");
+ EditorGUILayout.DelayedTextField(address, GUILayout.ExpandWidth(true));
+ UnityEngine.GUI.enabled = preAddressPrevEnabledState;
+ }
+ else
+ {
+ string newAddress = EditorGUILayout.DelayedTextField(entryInfo.Address, GUILayout.ExpandWidth(true));
+ if (newAddress != entryInfo.Address)
{
- entry.address = newAddress;
- AddressableAssetUtility.OpenAssetIfUsingVCIntegration(entry.parentGroup, true);
+ if (newAddress.Contains("[") && newAddress.Contains("]"))
+ Debug.LogErrorFormat("Rename of address '{0}' cannot contain '[ ]'.", entryInfo.Address);
+ else
+ {
+ entryInfo.MainAssetEntry.address = newAddress;
+ AddressableAssetUtility.OpenAssetIfUsingVCIntegration(entryInfo.MainAssetEntry.parentGroup, true);
+ }
}
}
}
else
{
- EditorGUILayout.LabelField(addressableCount + " out of " + editor.targets.Length + " assets are addressable.");
+ FindUniqueAssetGuids(targetInfos, out var uniqueAssetGuids, out var uniqueAddressableAssetGuids);
+ EditorGUILayout.LabelField(uniqueAddressableAssetGuids.Count + " out of " + uniqueAssetGuids.Count + " assets are addressable.");
}
- if (GUILayout.Button("Select"))
- SelectEntriesInGroupsWindow(targetInfos);
+ DrawSelectEntriesButton(targetInfos);
GUILayout.EndHorizontal();
}
- else
+ else // mixed addressable selected
{
GUILayout.BeginHorizontal();
if (s_ToggleMixed == null)
s_ToggleMixed = new GUIStyle("ToggleMixed");
if (GUILayout.Toggle(false, s_AddressableAssetToggleText, s_ToggleMixed, GUILayout.ExpandWidth(false)))
SetAaEntry(AddressableAssetSettingsDefaultObject.GetSettings(true), targetInfos, true);
- EditorGUILayout.LabelField(addressableCount + " out of " + editor.targets.Length + " assets are addressable.");
- if (GUILayout.Button("Select"))
- SelectEntriesInGroupsWindow(targetInfos);
+ FindUniqueAssetGuids(targetInfos, out var uniqueAssetGuids, out var uniqueAddressableAssetGuids);
+ EditorGUILayout.LabelField(uniqueAddressableAssetGuids.Count + " out of " + uniqueAssetGuids.Count + " assets are addressable.");
+ DrawSelectEntriesButton(targetInfos);
GUILayout.EndHorizontal();
}
UnityEngine.GUI.enabled = prevEnabledState;
}
}
- static void SelectEntriesInGroupsWindow(List targets)
+ internal static List GatherTargetInfos(Object[] targets, AddressableAssetSettings aaSettings)
{
- AddressableAssetsWindow.Init();
- var window = EditorWindow.GetWindow();
- List entries = new List(targets.Count);
- foreach (TargetInfo info in targets)
+ var targetInfos = new List();
+ AddressableAssetEntry entry;
+ foreach (var t in targets)
{
- if (info.Entry != null)
- entries.Add(info.Entry);
+ if (AddressableAssetUtility.TryGetPathAndGUIDFromTarget(t, out var path, out var guid))
+ {
+ var mainAssetType = AssetDatabase.GetMainAssetTypeAtPath(path);
+ // Is asset
+ if (mainAssetType != null && !BuildUtility.IsEditorAssembly(mainAssetType.Assembly))
+ {
+ bool isMainAsset = t is AssetImporter || AssetDatabase.IsMainAsset(t);
+ var info = new TargetInfo() {TargetObject = t, Guid = guid, Path = path, IsMainAsset = isMainAsset};
+
+ if (aaSettings != null)
+ {
+ entry = aaSettings.FindAssetEntry(guid, true);
+ if (entry != null)
+ info.MainAssetEntry = entry;
+ }
+
+ targetInfos.Add(info);
+ }
+ }
+ }
+
+ return targetInfos;
+ }
+
+ internal static void FindUniqueAssetGuids(List targetInfos, out HashSet uniqueAssetGuids, out HashSet uniqueAddressableAssetGuids)
+ {
+ uniqueAssetGuids = new HashSet();
+ uniqueAddressableAssetGuids = new HashSet();
+ foreach (TargetInfo info in targetInfos)
+ {
+ uniqueAssetGuids.Add(info.Guid);
+ if (info.MainAssetEntry != null)
+ uniqueAddressableAssetGuids.Add(info.Guid);
+ }
+ }
+
+ static void DrawSelectEntriesButton(List targets)
+ {
+ var prevGuiEnabled = UnityEngine.GUI.enabled;
+ UnityEngine.GUI.enabled = true;
+
+ if (GUILayout.Button("Select"))
+ {
+ AddressableAssetsWindow.Init();
+ var window = EditorWindow.GetWindow();
+ List entries = new List(targets.Count);
+ foreach (TargetInfo info in targets)
+ {
+ if (info.MainAssetEntry != null)
+ {
+ if (info.IsMainAsset == false && ProjectConfigData.ShowSubObjectsInGroupView)
+ {
+ List subs = new List();
+ info.MainAssetEntry.GatherAllAssets(subs, false, true, true);
+ foreach (AddressableAssetEntry sub in subs)
+ {
+ if (sub.TargetAsset == info.TargetObject)
+ {
+ entries.Add(sub);
+ break;
+ }
+ }
+ }
+ else
+ entries.Add(info.MainAssetEntry);
+ }
+ }
+
+ if (entries.Count > 0)
+ window.SelectAssetsInGroupEditor(entries);
}
- window.SelectAssetsInGroupEditor(entries);
+ UnityEngine.GUI.enabled = prevGuiEnabled;
}
- class TargetInfo
+ internal class TargetInfo
{
+ public UnityEngine.Object TargetObject;
public string Guid;
public string Path;
- public Type MainAssetType;
- public AddressableAssetEntry Entry;
+ public bool IsMainAsset;
+ public AddressableAssetEntry MainAssetEntry;
+
+ public string Address
+ {
+ get
+ {
+ if (MainAssetEntry == null)
+ throw new NullReferenceException("No Entry set for Target info with AssetPath " + Path);
+ return MainAssetEntry.address;
+ }
+ }
}
}
}
diff --git a/Editor/GUI/HostingServicesProfileVarsTreeView.cs b/Editor/GUI/HostingServicesProfileVarsTreeView.cs
index 312a8d67..b8147470 100644
--- a/Editor/GUI/HostingServicesProfileVarsTreeView.cs
+++ b/Editor/GUI/HostingServicesProfileVarsTreeView.cs
@@ -66,6 +66,11 @@ public static MultiColumnHeader CreateHeader()
readonly Dictionary m_ItemMap;
+ internal int Count
+ {
+ get { return m_ItemMap.Count; }
+ }
+
public float RowHeight
{
get { return rowHeight; }
diff --git a/Editor/GUI/HostingServicesWindow.cs b/Editor/GUI/HostingServicesWindow.cs
index 4041a6d6..fe06ee0b 100644
--- a/Editor/GUI/HostingServicesWindow.cs
+++ b/Editor/GUI/HostingServicesWindow.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using UnityEditor.AddressableAssets.HostingServices;
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.IMGUI.Controls;
@@ -58,6 +59,12 @@ public class HostingServicesWindow : EditorWindow, ISerializationCallbackReceive
readonly Dictionary
/// The id of the command.
- /// The groups to run the command on.
+ /// The groups to run the command on.
/// Returns true if the command was invoked successfully.
public static bool InvokeAssetGroupCommand(string cmdId, IEnumerable groups)
{
diff --git a/Editor/Settings/AddressableAssetUtility.cs b/Editor/Settings/AddressableAssetUtility.cs
index 58c2a3b8..56fe1dbb 100644
--- a/Editor/Settings/AddressableAssetUtility.cs
+++ b/Editor/Settings/AddressableAssetUtility.cs
@@ -21,9 +21,8 @@ internal static bool IsInResources(string path)
return path.Replace('\\', '/').ToLower().Contains("/resources/");
}
- internal static bool GetPathAndGUIDFromTarget(Object target, out string path, out string guid, out Type mainAssetType)
+ internal static bool TryGetPathAndGUIDFromTarget(Object target, out string path, out string guid)
{
- mainAssetType = null;
guid = string.Empty;
path = string.Empty;
if (target == null)
@@ -31,13 +30,7 @@ internal static bool GetPathAndGUIDFromTarget(Object target, out string path, ou
path = AssetDatabase.GetAssetOrScenePath(target);
if (!IsPathValidForEntry(path))
return false;
- guid = AssetDatabase.AssetPathToGUID(path);
- if (string.IsNullOrEmpty(guid))
- return false;
- mainAssetType = AssetDatabase.GetMainAssetTypeAtPath(path);
- if (mainAssetType == null)
- return false;
- if (mainAssetType != target.GetType() && !typeof(AssetImporter).IsAssignableFrom(target.GetType()))
+ if (!AssetDatabase.TryGetGUIDAndLocalFileIdentifier(target, out guid, out long id))
return false;
return true;
}
@@ -52,6 +45,13 @@ internal static bool IsPathValidForEntry(string path)
path == CommonStrings.UnityDefaultResourcePath ||
path == CommonStrings.UnityBuiltInExtraPath)
return false;
+ if (path.EndsWith("/Editor") || path.Contains("/Editor/"))
+ return false;
+ if (path == "Assets")
+ return false;
+ var settings = AddressableAssetSettingsDefaultObject.SettingsExists ? AddressableAssetSettingsDefaultObject.Settings : null;
+ if (settings != null && path.StartsWith(settings.ConfigFolder) || path.StartsWith(AddressableAssetSettingsDefaultObject.kDefaultConfigFolder))
+ return false;
return !excludedExtensions.Contains(Path.GetExtension(path));
}
diff --git a/Runtime/Addressables.cs b/Runtime/Addressables.cs
index 9ae22e5a..0ffdc899 100644
--- a/Runtime/Addressables.cs
+++ b/Runtime/Addressables.cs
@@ -635,6 +635,7 @@ public static AsyncOperationHandle> LoadAssetsAsync(IEnu
/// down to one based on the provided MergeMode.
/// See the [Loading Addressable Assets](xref:addressables-api-load-asset-async) documentation for more details.
///
+ /// The type of the assets.
/// IEnumerable set of keys for the locations.
/// Callback Action that is called per load operation.
/// Method for merging the results of key matches. See for specifics
@@ -658,6 +659,7 @@ public static AsyncOperationHandle> LoadAssetsAsync(ILis
/// down to one based on the provided MergeMode.
/// See the [Loading Addressable Assets](xref:addressables-api-load-asset-async) documentation for more details.
///
+ /// The type of the assets.
/// IEnumerable set of keys for the locations.
/// Callback Action that is called per load operation.
/// Method for merging the results of key matches. See for specifics
@@ -955,7 +957,7 @@ public static void ClearDependencyCacheAsync(IEnumerable keys)
/// Clear the cached AssetBundles for a list of Addressable keys. Operation may be performed async if Addressables
/// is initializing or updating.
///
- /// The key to clear the cache for.
+ /// The key to clear the cache for.
public static void ClearDependencyCacheAsync(string key)
{
m_Addressables.ClearDependencyCacheAsync((object)key, true);
@@ -1014,7 +1016,7 @@ public static AsyncOperationHandle ClearDependencyCacheAsync(IEnumerable k
/// Clear the cached AssetBundles for a list of Addressable keys. Operation may be performed async if Addressables
/// is initializing or updating.
///
- /// The keys to clear the cache for.
+ /// The keys to clear the cache for.
/// If true, the returned AsyncOperationHandle will be released on completion.
/// The operation handle for the request.
public static AsyncOperationHandle ClearDependencyCacheAsync(string key, bool autoReleaseHandle)
diff --git a/Runtime/AssetReference.cs b/Runtime/AssetReference.cs
index 9a9c6273..8fbd0d1a 100644
--- a/Runtime/AssetReference.cs
+++ b/Runtime/AssetReference.cs
@@ -66,7 +66,7 @@ public override bool ValidateAsset(Object obj)
/// Validates that the asset located at a path is allowable for this asset reference. An asset is allowable if
/// it is of the correct type or if one of its sub-asset is.
///
- /// The path to the asset in question.
+ /// The path to the asset in question.
/// Whether the referenced asset is valid.
public override bool ValidateAsset(string mainAssetPath)
{
diff --git a/Runtime/Initialization/PackedPlayModeBuildLogs.cs b/Runtime/Initialization/PackedPlayModeBuildLogs.cs
index f4741408..f4fa9d44 100644
--- a/Runtime/Initialization/PackedPlayModeBuildLogs.cs
+++ b/Runtime/Initialization/PackedPlayModeBuildLogs.cs
@@ -3,6 +3,9 @@
using System.Collections.Generic;
using UnityEngine;
+///
+/// Creates build logs that need to be seen at runtime.
+///
[Serializable]
public class PackedPlayModeBuildLogs
{
diff --git a/Runtime/ResourceLocators/ResourceLocationData.cs b/Runtime/ResourceLocators/ResourceLocationData.cs
index 76e58e2f..79419a27 100644
--- a/Runtime/ResourceLocators/ResourceLocationData.cs
+++ b/Runtime/ResourceLocators/ResourceLocationData.cs
@@ -49,12 +49,12 @@ public class ResourceLocationData
///
public Type ResourceType { get { return m_ResourceType.Value; } }
- ///
- /// The optional arbitrary data stored along with location
- ///
[SerializeField]
byte[] SerializedData;
object _Data;
+ ///
+ /// The optional arbitrary data stored along with location
+ ///
public object Data
{
get
diff --git a/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs b/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs
index 16ea98fe..54636127 100644
--- a/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs
+++ b/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs
@@ -151,7 +151,10 @@ internal void IncrementReferenceCount()
///
public void WaitForCompletion()
{
- while (!InvokeWaitForCompletion()) {}
+ if (Application.platform != RuntimePlatform.WebGLPlayer)
+ while (!InvokeWaitForCompletion()) { }
+ else
+ throw new Exception($"WebGL does not support synchronous Addressable loading. Please do not use WaitForCompletion on the WebGL platform.");
}
///
diff --git a/Runtime/ResourceManager/AsyncOperations/ProviderOperation.cs b/Runtime/ResourceManager/AsyncOperations/ProviderOperation.cs
index 198af150..404fe8d1 100644
--- a/Runtime/ResourceManager/AsyncOperations/ProviderOperation.cs
+++ b/Runtime/ResourceManager/AsyncOperations/ProviderOperation.cs
@@ -65,6 +65,8 @@ protected override bool InvokeWaitForCompletion()
m_RM?.Update(Time.deltaTime);
if (!HasExecuted)
InvokeExecute();
+ if (m_WaitForCompletionCallback == null)
+ return false;
return m_WaitForCompletionCallback.Invoke();
}
@@ -149,6 +151,7 @@ public void ProviderCompleted(T result, bool status, Exception e)
m_ProvideHandleVersion++;
m_GetProgressCallback = null;
m_GetDownloadProgressCallback = null;
+ m_WaitForCompletionCallback = null;
m_NeedsRelease = status;
ProviderOperation top = this as ProviderOperation;
diff --git a/Runtime/ResourceManager/Util/OperationCacheKeys.cs b/Runtime/ResourceManager/Util/OperationCacheKeys.cs
index 47808e53..917df340 100644
--- a/Runtime/ResourceManager/Util/OperationCacheKeys.cs
+++ b/Runtime/ResourceManager/Util/OperationCacheKeys.cs
@@ -95,20 +95,10 @@ public static bool LocationEquals(IResourceLocation loc1, IResourceLocation loc2
if (ReferenceEquals(loc1, loc2)) return true;
if (ReferenceEquals(loc1, null)) return false;
if (ReferenceEquals(loc2, null)) return false;
- if (loc1.GetType() != loc2.GetType()) return false;
- bool membersEqual = loc1.PrimaryKey == loc2.PrimaryKey
- && loc1.InternalId == loc2.InternalId
- && loc1.ProviderId == loc2.ProviderId
- && loc1.ResourceType == loc2.ResourceType;
-
- if (!membersEqual)
- return false;
-
- if (loc1.HasDependencies != loc2.HasDependencies)
- return false;
-
- return DependenciesEqual(loc1.Dependencies, loc2.Dependencies);
+ return (loc1.InternalId.Equals(loc2.InternalId)
+ && loc1.ProviderId.Equals(loc2.ProviderId)
+ && loc1.ResourceType.Equals(loc2.ResourceType));
}
public static bool DependenciesEqual(IList deps1, IList deps2)
diff --git a/Tests/Editor/AddressableAssetFolderSubfolderTests.cs b/Tests/Editor/AddressableAssetFolderSubfolderTests.cs
index 99dec687..ec535d49 100644
--- a/Tests/Editor/AddressableAssetFolderSubfolderTests.cs
+++ b/Tests/Editor/AddressableAssetFolderSubfolderTests.cs
@@ -35,7 +35,7 @@ public class AddressableAssetFolderSubfolderTests : AddressableAssetTestBase
protected override void OnInit()
{
// Create directories
- m_TestFolderPath = ConfigFolder;
+ m_TestFolderPath = TestFolder;
m_AddrParentFolderPath = m_TestFolderPath + "/AddrParentFolder";
m_AddrChildSubfolderPath = m_AddrParentFolderPath + "/AddrChildSubfolder";
diff --git a/Tests/Editor/AddressableAssetSettingsTests.cs b/Tests/Editor/AddressableAssetSettingsTests.cs
index 0c704e20..0e90baff 100644
--- a/Tests/Editor/AddressableAssetSettingsTests.cs
+++ b/Tests/Editor/AddressableAssetSettingsTests.cs
@@ -483,7 +483,7 @@ public void AddressableAssetSettings_OnPostprocessAllAssets_AddAssetEntriesColle
var deletedAssets = new string[0];
var movedAssets = new string[0];
var movedFromAssetPaths = new string[0];
- var collectionPath = Path.Combine(ConfigFolder, "collection.asset").Replace('\\', '/');
+ var collectionPath = Path.Combine(TestFolder, "collection.asset").Replace('\\', '/');
var collection = ScriptableObject.CreateInstance();
var entry = new AddressableAssetEntry("12345698655", "TestAssetEntry", null, false);
entry.m_cachedAssetPath = "TestPath";
@@ -534,7 +534,7 @@ public void AddressableAssetSettings_OnPostprocessAllAssets_ChangeImportedAssets
var entry = Settings.CreateOrMoveEntry(m_AssetGUID, Settings.groups[0]);
var prevTestObjName = entry.MainAsset.name;
entry.MainAsset.name = "test";
- importedAssets[0] = ConfigFolder + "/test.prefab";
+ importedAssets[0] = TestFolder + "/test.prefab";
EditorUtility.ClearDirty(Settings);
var prevDC = EditorUtility.GetDirtyCount(Settings);
Settings.OnPostprocessAllAssets(importedAssets, deletedAssets, movedAssets, movedFromAssetPaths);
@@ -581,11 +581,11 @@ public void AddressableAssetSettings_OnPostprocessAllAssets_MovedAssetToResource
var deletedAssets = new string[0];
var movedAssets = new string[1];
var movedFromAssetPaths = new string[1];
- var assetPath = ConfigFolder + "/test.prefab";
- var newAssetPath = ConfigFolder + "/resources/test.prefab";
- if (!Directory.Exists(ConfigFolder + "/resources"))
+ var assetPath = TestFolder + "/test.prefab";
+ var newAssetPath = TestFolder + "/resources/test.prefab";
+ if (!Directory.Exists(TestFolder + "/resources"))
{
- Directory.CreateDirectory(ConfigFolder + "/resources");
+ Directory.CreateDirectory(TestFolder + "/resources");
AssetDatabase.Refresh();
}
Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(newAssetPath), Settings.groups[0]);
@@ -600,7 +600,7 @@ public void AddressableAssetSettings_OnPostprocessAllAssets_MovedAssetToResource
// Cleanup
AssetDatabase.MoveAsset(newAssetPath, assetPath);
Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(assetPath), Settings.groups[0]);
- Directory.Delete(ConfigFolder + "/resources");
+ Directory.Delete(TestFolder + "/resources");
}
[Test]
@@ -1001,7 +1001,7 @@ public void AddressableAssetSettings_MoveAssetsFromResources_CanMoveAssetsFromRe
var prevPath = AssetDatabase.GUIDToAssetPath(m_AssetGUID);
var prevPathTwo = AssetDatabase.GUIDToAssetPath(testAssetGUID);
var testGroup = Settings.FindGroup(AddressableAssetSettings.DefaultLocalGroupName);
- var testAssetPath = ConfigFolder + "/testMoveAssets";
+ var testAssetPath = TestFolder + "/testMoveAssets";
testGuidsToPaths[m_AssetGUID] = testAssetPath + "/resources/test.prefab";
testGuidsToPaths[testAssetGUID] = testAssetPath + "/resources/testasset.prefab";
@@ -1014,8 +1014,8 @@ public void AddressableAssetSettings_MoveAssetsFromResources_CanMoveAssetsFromRe
Assert.AreNotEqual(prevGroup, Settings.FindAssetEntry(testAssetGUID).parentGroup);
Assert.AreEqual(prevDC + 1, dc);
- testGuidsToPaths[m_AssetGUID] = ConfigFolder + "/test.prefab";
- testGuidsToPaths[testAssetGUID] = ConfigFolder + "/testasset.prefab";
+ testGuidsToPaths[m_AssetGUID] = TestFolder + "/test.prefab";
+ testGuidsToPaths[testAssetGUID] = TestFolder + "/testasset.prefab";
Settings.MoveAssetsFromResources(testGuidsToPaths, prevGroup);
originalAssetEntry = Settings.FindAssetEntry(m_AssetGUID);
Assert.AreEqual(originalAssetEntry.address, "test");
@@ -1034,7 +1034,7 @@ public void AddressableAssetSettings_MoveAssetsFromResources_AddressRespectFolde
var guidsToPaths = new Dictionary();
var obj = new GameObject("TestObjectMoveAssets");
- var objFolder = ConfigFolder + "/Resources/subfolder/subsubfolder";
+ var objFolder = TestFolder + "/Resources/subfolder/subsubfolder";
if (!Directory.Exists(objFolder))
{
Directory.CreateDirectory(objFolder);
@@ -1047,7 +1047,7 @@ public void AddressableAssetSettings_MoveAssetsFromResources_AddressRespectFolde
var playerDataGroup = Settings.FindGroup(AddressableAssetSettings.PlayerDataGroupName);
Settings.CreateOrMoveEntry(guid, playerDataGroup);
- var destinationFolder = ConfigFolder + "/testMoveAssets";
+ var destinationFolder = TestFolder + "/testMoveAssets";
guidsToPaths[guid] = destinationFolder + "/testasset.prefab";
// Test
@@ -1062,9 +1062,9 @@ public void AddressableAssetSettings_MoveAssetsFromResources_AddressRespectFolde
Assert.AreEqual(defaultLocalGroup, entry.parentGroup);
//Cleanup
- if (Directory.Exists(ConfigFolder + "/Resources"))
- AssetDatabase.DeleteAsset(ConfigFolder + "/Resources");
- EditorBuildSettings.RemoveConfigObject(ConfigFolder + "/Resources");
+ if (Directory.Exists(TestFolder + "/Resources"))
+ AssetDatabase.DeleteAsset(TestFolder + "/Resources");
+ EditorBuildSettings.RemoveConfigObject(TestFolder + "/Resources");
Settings.RemoveAssetEntry(guid);
AssetDatabase.DeleteAsset(guidsToPaths[guid]);
@@ -1081,7 +1081,7 @@ public void AddressableAssetSettings_MoveAssetsFromResources_CannotMoveNullOrInv
var currentGroup = testAssetEntry.parentGroup;
var testGuidsToPaths = new Dictionary();
var currentPath = AssetDatabase.GUIDToAssetPath(m_AssetGUID);
- var newAssetPath = ConfigFolder + "/testMoveAssets";
+ var newAssetPath = TestFolder + "/testMoveAssets";
testGuidsToPaths[m_AssetGUID] = newAssetPath + "/test.prefab";
Settings.MoveAssetsFromResources(testGuidsToPaths, null);
Settings.MoveEntry(testAssetEntry, null);
diff --git a/Tests/Editor/AddressableAssetTestBase.cs b/Tests/Editor/AddressableAssetTestBase.cs
index 798ed39b..81f3be70 100644
--- a/Tests/Editor/AddressableAssetTestBase.cs
+++ b/Tests/Editor/AddressableAssetTestBase.cs
@@ -12,10 +12,15 @@ namespace UnityEditor.AddressableAssets.Tests
public abstract class AddressableAssetTestBase
{
protected const string k_TestConfigName = "AddressableAssetSettings.Tests";
- protected string ConfigFolder => $"Assets/{GetType()}_Tests";
+
+ protected string TestFolder => $"Assets/{TestFolderName}";
+ protected string TestFolderName => $"{GetType()}_Tests";
+ protected string ConfigFolder => TestFolder + "/Config";
+
+
protected string GetAssetPath(string assetName)
{
- return $"{ConfigFolder}/{assetName}";
+ return $"{TestFolder}/{assetName}";
}
private AddressableAssetSettings m_Settings;
@@ -39,36 +44,29 @@ public void Init()
//TODO: Remove when NSImage warning issue on bokken is fixed
Application.logMessageReceived += CheckLogForWarning;
- if (Directory.Exists(ConfigFolder))
- {
- Debug.Log($"{GetType()} (init) - deleting {ConfigFolder}");
- AssetDatabase.DeleteAsset(ConfigFolder);
- }
- if (!Directory.Exists(ConfigFolder))
+ if (Directory.Exists(TestFolder))
{
- Debug.Log($"{GetType()} (init) - creating {ConfigFolder}");
- Directory.CreateDirectory(ConfigFolder);
- AssetDatabase.Refresh();
+ Debug.Log($"{GetType()} (init) - deleting {TestFolder}");
+ if (!AssetDatabase.DeleteAsset(TestFolder))
+ Directory.Delete(TestFolder);
}
+
+ Debug.Log($"{GetType()} (init) - creating {TestFolder}");
+ AssetDatabase.CreateFolder("Assets", TestFolderName);
+ AssetDatabase.CreateFolder(TestFolder, "Config");
Settings.labelTable.labelNames.Clear();
GameObject testObject = new GameObject("TestObject");
GameObject testObject1 = new GameObject("TestObject 1");
GameObject testObject2 = new GameObject("TestObject 2");
-#if UNITY_2018_3_OR_NEWER
- PrefabUtility.SaveAsPrefabAsset(testObject, ConfigFolder + "/test.prefab");
- PrefabUtility.SaveAsPrefabAsset(testObject1, ConfigFolder + "/test 1.prefab");
- PrefabUtility.SaveAsPrefabAsset(testObject2, ConfigFolder + "/test 2.prefab");
-#else
- PrefabUtility.CreatePrefab(k_TestConfigFolder + "/test.prefab", testObject);
- PrefabUtility.CreatePrefab(k_TestConfigFolder + "/test 1.prefab", testObject1);
- PrefabUtility.CreatePrefab(k_TestConfigFolder + "/test 2.prefab", testObject2);
-#endif
- m_AssetGUID = AssetDatabase.AssetPathToGUID(ConfigFolder + "/test.prefab");
-
- string scene1Path = ConfigFolder + "/contentUpdateScene1.unity";
- string scene2Path = ConfigFolder + "/contentUpdateScene2.unity";
- string scene3Path = ConfigFolder + "/contentUpdateScene3.unity";
+ PrefabUtility.SaveAsPrefabAsset(testObject, TestFolder + "/test.prefab");
+ PrefabUtility.SaveAsPrefabAsset(testObject1, TestFolder + "/test 1.prefab");
+ PrefabUtility.SaveAsPrefabAsset(testObject2, TestFolder + "/test 2.prefab");
+ m_AssetGUID = AssetDatabase.AssetPathToGUID(TestFolder + "/test.prefab");
+
+ string scene1Path = TestFolder + "/contentUpdateScene1.unity";
+ string scene2Path = TestFolder + "/contentUpdateScene2.unity";
+ string scene3Path = TestFolder + "/contentUpdateScene3.unity";
Scene scene1 = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
EditorSceneManager.SaveScene(scene1, scene1Path);
@@ -113,10 +111,10 @@ protected virtual void OnInit() {}
public void Cleanup()
{
OnCleanup();
- if (Directory.Exists(ConfigFolder))
+ if (Directory.Exists(TestFolder))
{
- Debug.Log($"{GetType()} - (cleanup) deleting {ConfigFolder}");
- AssetDatabase.DeleteAsset(ConfigFolder);
+ Debug.Log($"{GetType()} - (cleanup) deleting {TestFolder}");
+ AssetDatabase.DeleteAsset(TestFolder);
}
EditorBuildSettings.RemoveConfigObject(k_TestConfigName);
}
diff --git a/Tests/Editor/AddressableAssetUtilityTests.cs b/Tests/Editor/AddressableAssetUtilityTests.cs
index 2776ada2..e8fc7601 100644
--- a/Tests/Editor/AddressableAssetUtilityTests.cs
+++ b/Tests/Editor/AddressableAssetUtilityTests.cs
@@ -28,10 +28,10 @@ public void GetPathAndGUIDFromTarget_FromPrefabAsset_ReturnsCorrectPathGUIDType(
var expectedGUID = CreateTestPrefabAsset(GetAssetPath("prefab1.prefab"), "prefab1");
var expectedPath = AssetDatabase.GUIDToAssetPath(expectedGUID);
var obj = AssetDatabase.LoadAssetAtPath(expectedPath);
- Assert.IsTrue(AddressableAssetUtility.GetPathAndGUIDFromTarget(obj, out var actualPath, out var actualGUID, out var actualType));
+ Assert.IsTrue(AddressableAssetUtility.IsPathValidForEntry(expectedPath), $"Asset is not a valid Addressable Entry path : {expectedPath}");
+ Assert.IsTrue(AddressableAssetUtility.TryGetPathAndGUIDFromTarget(obj, out var actualPath, out var actualGUID), "Could not get Path and Guid from Target at expectedPath " + expectedPath);
Assert.AreEqual(expectedPath, actualPath);
Assert.AreEqual(expectedGUID, actualGUID);
- Assert.AreEqual(typeof(GameObject), actualType);
AssetDatabase.DeleteAsset(expectedPath);
}
@@ -39,11 +39,10 @@ public void GetPathAndGUIDFromTarget_FromPrefabAsset_ReturnsCorrectPathGUIDType(
public void GetPathAndGUIDFromTarget_FromPrefabObject_Fails()
{
var obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
- Assert.IsFalse(AddressableAssetUtility.GetPathAndGUIDFromTarget(obj, out var actualPath, out var actualGUID, out var actualType));
+ Assert.IsFalse(AddressableAssetUtility.TryGetPathAndGUIDFromTarget(obj, out var actualPath, out var actualGUID));
Assert.IsEmpty(actualPath);
Assert.IsEmpty(actualGUID);
Assert.IsEmpty(actualGUID);
- Assert.IsNull(actualType);
}
[Test]
@@ -57,11 +56,10 @@ public void GetPackages_ReturnsUnityPackages()
[Test]
public void GetPathAndGUIDFromTarget_FromNullObject_Fails()
{
- Assert.IsFalse(AddressableAssetUtility.GetPathAndGUIDFromTarget(null, out var actualPath, out var actualGUID, out var actualType));
+ Assert.IsFalse(AddressableAssetUtility.TryGetPathAndGUIDFromTarget(null, out var actualPath, out var actualGUID));
Assert.IsEmpty(actualPath);
Assert.IsEmpty(actualGUID);
Assert.IsEmpty(actualGUID);
- Assert.IsNull(actualType);
}
public class TestBaseClass { }
@@ -223,15 +221,15 @@ public void AreConvertableEditorAssemblyTypesConverted()
[Test]
public void SafeMoveResourcesToGroup_ResourcesMovedToNewFolderAndGroup()
{
- var folderPath = AssetDatabase.GUIDToAssetPath(AssetDatabase.CreateFolder(ConfigFolder, "Resources"));
+ var folderPath = AssetDatabase.GUIDToAssetPath(AssetDatabase.CreateFolder(TestFolder, "Resources"));
var g1 = CreateTestPrefabAsset(folderPath + "/p1.prefab", "p1");
var g2 = CreateTestPrefabAsset(folderPath + "/p2.prefab", "p2");
Assert.AreEqual(0, Settings.DefaultGroup.entries.Count);
var result = AddressableAssetUtility.SafeMoveResourcesToGroup(Settings, Settings.DefaultGroup, new List { AssetDatabase.GUIDToAssetPath(g1), AssetDatabase.GUIDToAssetPath(g2) }, null, false);
Assert.IsTrue(result);
Assert.AreEqual(2, Settings.DefaultGroup.entries.Count);
- var ap = $"{ConfigFolder}_Resources_moved";
- Assert.IsTrue(AssetDatabase.IsValidFolder($"{ConfigFolder}/Resources_moved"));
+ var ap = $"{TestFolder}_Resources_moved";
+ Assert.IsTrue(AssetDatabase.IsValidFolder($"{TestFolder}/Resources_moved"));
}
[Test]
@@ -259,5 +257,78 @@ public void BundledAssetGroupSchema_GetAssetLoadPath_Returns_ExpectedId(int imod
var actualId = bas.GetAssetLoadPath(assetPath, otherInternaIds, s => guid);
Assert.AreEqual(expectedId, actualId);
}
+
+ [Test]
+ public void InspectorGUI_GatherTargetinfo_AllAddressable()
+ {
+ string path1 = GetAssetPath("test.prefab");
+ string guid1 = AssetDatabase.AssetPathToGUID(path1);
+ Settings.CreateOrMoveEntry(guid1, Settings.DefaultGroup);
+ string path2 = GetAssetPath("test 1.prefab");
+ string guid2 = AssetDatabase.AssetPathToGUID(path2);
+ Settings.CreateOrMoveEntry(guid2, Settings.DefaultGroup);
+
+ UnityEngine.Object[] targets = new UnityEngine.Object[2];
+ targets[0] = AssetDatabase.LoadAssetAtPath(path1);
+ targets[1] = AssetDatabase.LoadAssetAtPath(path2);
+ var infos = UnityEditor.AddressableAssets.GUI.AddressableAssetInspectorGUI.GatherTargetInfos(targets, Settings);
+
+ Assert.AreEqual(2, infos.Count);
+ Assert.NotNull(infos[0].MainAssetEntry);
+ Assert.NotNull(infos[1].MainAssetEntry);
+
+ // clean up
+ Settings.RemoveAssetEntry(guid1);
+ Settings.RemoveAssetEntry(guid2);
+ }
+
+ [Test]
+ public void InspectorGUI_GatherTargetinfo_MixedAddressable()
+ {
+ string path1 = GetAssetPath("test.prefab");
+ string guid1 = AssetDatabase.AssetPathToGUID(path1);
+ Settings.CreateOrMoveEntry(guid1, Settings.DefaultGroup);
+ string path2 = GetAssetPath("test 1.prefab");
+
+ UnityEngine.Object[] targets = new UnityEngine.Object[2];
+ targets[0] = AssetDatabase.LoadAssetAtPath(path1);
+ targets[1] = AssetDatabase.LoadAssetAtPath(path2);
+ var infos = UnityEditor.AddressableAssets.GUI.AddressableAssetInspectorGUI.GatherTargetInfos(targets, Settings);
+
+ Assert.AreEqual(2, infos.Count);
+ Assert.NotNull(infos[0].MainAssetEntry);
+ Assert.IsNull(infos[1].MainAssetEntry);
+
+ // clean up
+ Settings.RemoveAssetEntry(guid1);
+ }
+
+ [Test]
+ public void InspectorGUI_FindUniqueAssetGuids_CorrectAssetCount()
+ {
+ string path1 = GetAssetPath("test.prefab");
+ string guid1 = AssetDatabase.AssetPathToGUID(path1);
+ Settings.CreateOrMoveEntry(guid1, Settings.DefaultGroup);
+ string path2 = GetAssetPath("test 1.prefab");
+
+ UnityEngine.Object[] targets = new UnityEngine.Object[2];
+ targets[0] = AssetDatabase.LoadAssetAtPath(path1);
+ targets[1] = AssetDatabase.LoadAssetAtPath(path2);
+ var infos = UnityEditor.AddressableAssets.GUI.AddressableAssetInspectorGUI.GatherTargetInfos(targets, Settings);
+
+ Assert.AreEqual(2, infos.Count);
+ Assert.NotNull(infos[0].MainAssetEntry);
+ Assert.IsNull(infos[1].MainAssetEntry);
+
+ infos.Add(infos[0]);
+ infos.Add(infos[1]);
+ UnityEditor.AddressableAssets.GUI.AddressableAssetInspectorGUI.FindUniqueAssetGuids(infos, out var uniqueAssetGuids, out var uniqueAddressableAssetGuids);
+
+ Assert.AreEqual(2, uniqueAssetGuids.Count);
+ Assert.AreEqual(1, uniqueAddressableAssetGuids.Count);
+
+ // clean up
+ Settings.RemoveAssetEntry(guid1);
+ }
}
}
diff --git a/Tests/Editor/AddressableAssetsWindowTests.cs b/Tests/Editor/AddressableAssetsWindowTests.cs
index 5f6c5619..aea68962 100644
--- a/Tests/Editor/AddressableAssetsWindowTests.cs
+++ b/Tests/Editor/AddressableAssetsWindowTests.cs
@@ -85,10 +85,25 @@ public void AddressableAssetWindow_CanSelectGroupTreeViewByAddressableAssetEntri
//Setup
var defaultGroup = Settings.DefaultGroup;
Assert.IsNotNull(defaultGroup, "Default Group is not found");
+ ProjectConfigData.ShowSubObjectsInGroupView = true;
+
+ string path0 = GetAssetPath("test.prefab");
+ string p0 = AssetDatabase.AssetPathToGUID(path0);
+ Assert.IsFalse(string.IsNullOrEmpty(p0), "Could not setup for Asset \"test.prefab\"");
+ Texture t = new Texture2D(4, 4);
+ t.name = "tex";
+ AssetDatabase.AddObjectToAsset(t, path0);
+ AssetDatabase.SaveAssets();
string p1 = AssetDatabase.AssetPathToGUID(GetAssetPath("test 1.prefab"));
Assert.IsFalse(string.IsNullOrEmpty(p1), "Could not setup for Asset \"test 1.prefab\"");
string p2 = AssetDatabase.AssetPathToGUID(GetAssetPath("test 2.prefab"));
Assert.IsFalse(string.IsNullOrEmpty(p2), "Could not setup for Asset \"test 2.prefab\"");
+
+ var e0 = Settings.CreateOrMoveEntry(p0, defaultGroup);
+ List gathered = new List();
+ e0.GatherAllAssets(gathered, false, true, true);
+ Assert.AreEqual(1, gathered.Count, "Incorrect subObject count for Asset at " + path0 );
+
var e1 = Settings.CreateOrMoveEntry(p1, defaultGroup);
var e2 = Settings.CreateOrMoveEntry(p2, defaultGroup);
@@ -107,6 +122,10 @@ public void AddressableAssetWindow_CanSelectGroupTreeViewByAddressableAssetEntri
aaWindow.SelectAssetsInGroupEditor(new List(){e1, e2});
Assert.AreEqual(2, entryTree.GetSelection().Count, "Expecting to have \"test 1.prefab\" and \"test 2.prefab\" selected.");
+ Assert.IsTrue(ProjectConfigData.ShowSubObjectsInGroupView, "Need to display subObjects to test that they are being shown");
+ aaWindow.SelectAssetsInGroupEditor(new List(){gathered[0]});
+ Assert.AreEqual(1, entryTree.GetSelection().Count, "Expecting to have \"test.prefab[SubObject]\" selected.");
+
//Cleanup
Assert.IsTrue(Settings.RemoveAssetEntry(e1, false), "Failed to cleanup AssetEntry \"test 1.prefab\" from test settings.");
Assert.IsTrue(Settings.RemoveAssetEntry(e2, false), "Failed to cleanup AssetEntry \"test 2.prefab\" from test settings.");
diff --git a/Tests/Editor/Build/BuildScriptPackedTests.cs b/Tests/Editor/Build/BuildScriptPackedTests.cs
index f3ce567b..8fcff55c 100644
--- a/Tests/Editor/Build/BuildScriptPackedTests.cs
+++ b/Tests/Editor/Build/BuildScriptPackedTests.cs
@@ -194,11 +194,11 @@ public void CatalogBuiltWithDifferentGroupOrder_AreEqualWhenOrderEnabled()
AddressableAssetGroup group1 = Settings.CreateGroup("simpleGroup1", false, false, false,
new List(), typeof(BundledAssetGroupSchema));
- Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(Path.Combine(ConfigFolder, "test 1.prefab")),
+ Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(Path.Combine(TestFolder, "test 1.prefab")),
group1, false, false);
AddressableAssetGroup group2 = Settings.CreateGroup("simpleGroup2", false, false, false,
new List(), typeof(BundledAssetGroupSchema));
- Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(Path.Combine(ConfigFolder, "test 2.prefab")),
+ Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(Path.Combine(TestFolder, "test 2.prefab")),
group2, false, false);
var r1 = buildScript.BuildData(m_BuilderInput);
diff --git a/Tests/Editor/Build/BuildScriptTests.cs b/Tests/Editor/Build/BuildScriptTests.cs
index 20d1bbaa..ac5c5f4a 100644
--- a/Tests/Editor/Build/BuildScriptTests.cs
+++ b/Tests/Editor/Build/BuildScriptTests.cs
@@ -68,8 +68,8 @@ public void ClearCachedData_CleansStreamingAssetFolder()
public void Folder_WithSubAssets_GetsBundleFileIdAssigned_DuringBuild()
{
var context = new AddressablesDataBuilderInput(Settings);
- string folderGuid = AssetDatabase.CreateFolder(ConfigFolder, "FolderAsset");
- string folderPath = $"{ConfigFolder}/FolderAsset";
+ string folderGuid = AssetDatabase.CreateFolder(TestFolder, "FolderAsset");
+ string folderPath = $"{TestFolder}/FolderAsset";
PrefabUtility.SaveAsPrefabAsset(new GameObject(), $"{folderPath}/subfolderprefab.prefab");
AddressableAssetEntry folderEntry = Settings.CreateOrMoveEntry(folderGuid, Settings.DefaultGroup);
@@ -90,8 +90,8 @@ public void Folder_WithSubAssets_GetsBundleFileIdAssigned_DuringBuild()
public void Folder_WithNoSubAssets_DoesNotThrowErrorDuringBuild()
{
var context = new AddressablesDataBuilderInput(Settings);
- string folderGuid = AssetDatabase.CreateFolder(ConfigFolder, "FolderAsset");
- string folderPath = $"{ConfigFolder}/FolderAsset";
+ string folderGuid = AssetDatabase.CreateFolder(TestFolder, "FolderAsset");
+ string folderPath = $"{TestFolder}/FolderAsset";
AddressableAssetEntry folderEntry = Settings.CreateOrMoveEntry(folderGuid, Settings.DefaultGroup);
@@ -111,8 +111,8 @@ public void Folder_WithNoSubAssets_DoesNotThrowErrorDuringBuild()
public void Folder_DoesNotAssignBundleFileId_ForDynamicallyCreatedSubEntries()
{
var context = new AddressablesDataBuilderInput(Settings);
- string folderGuid = AssetDatabase.CreateFolder(ConfigFolder, "FolderAsset");
- string folderPath = $"{ConfigFolder}/FolderAsset";
+ string folderGuid = AssetDatabase.CreateFolder(TestFolder, "FolderAsset");
+ string folderPath = $"{TestFolder}/FolderAsset";
PrefabUtility.SaveAsPrefabAsset(new GameObject(), $"{folderPath}/subfolderprefab.prefab");
AddressableAssetEntry folderEntry = Settings.CreateOrMoveEntry(folderGuid, Settings.DefaultGroup);
diff --git a/Tests/Editor/ContentUpdateTests.cs b/Tests/Editor/ContentUpdateTests.cs
index 005c55a2..e23d5613 100644
--- a/Tests/Editor/ContentUpdateTests.cs
+++ b/Tests/Editor/ContentUpdateTests.cs
@@ -1197,5 +1197,15 @@ public void ApplyAssetEntryUpdates_WhenAssetAndDependencyAreModifiedAndInSeparat
Settings.RemoveGroup(group);
Settings.RemoveGroup(depGroup);
}
+
+ [Test]
+ [TestCase("{Addressables.RuntimePath}/TargetPlatform/prefabA.bundle", "{Addressables.RuntimePath}/TargetPlatform", "Library/aa/TargetPlatform")]
+ [TestCase("{Addressables.RuntimePath}\\TargetPlatform\\prefabA.bundle", "{Addressables.RuntimePath}/TargetPlatform", "Library/aa/TargetPlatform")]
+ [TestCase("http://localhost/TargetPlatform/prefabA.bundle", "http://localhost/TargetPlatform", "ServerData/TargetPlatform")]
+ public void BundleIdToBuildPath_ReturnsBundleBuildPath(string bundleId, string rootLoadPath, string rootBuildPath)
+ {
+ string buildPath = RevertUnchangedAssetsToPreviousAssetState.BundleIdToBuildPath(bundleId, rootLoadPath, rootBuildPath);
+ Assert.IsTrue(buildPath.StartsWith(rootBuildPath));
+ }
}
}
diff --git a/Tests/Editor/HostingServices/HostingServicesWindowUtilitiesTests.cs b/Tests/Editor/HostingServices/HostingServicesWindowUtilitiesTests.cs
new file mode 100644
index 00000000..d58d8095
--- /dev/null
+++ b/Tests/Editor/HostingServices/HostingServicesWindowUtilitiesTests.cs
@@ -0,0 +1,99 @@
+using System.Collections;
+using System.Collections.Generic;
+using NUnit.Framework;
+using UnityEditor.AddressableAssets.GUI;
+
+namespace UnityEditor.AddressableAssets.Tests.HostingServices
+{
+ public class HostingServicesWindowUtilitiesTests
+ {
+ [Test]
+ public void DictsAreEqual_ReturnsTrueOnSameValueSameRef()
+ {
+ var originalDict = new Dictionary();
+ originalDict.Add("a", "1");
+ originalDict.Add("b", "2");
+ originalDict.Add("c", "3");
+ var copyDict = originalDict;
+
+ Assert.IsTrue(HostingServicesWindow.DictsAreEqual(originalDict, copyDict), "Copy of dictionary should be equal to original, but isn't.");
+ }
+
+ [Test]
+ public void DictsAreEqual_ReturnsTrueOnSameValuesDifRef()
+ {
+ var dict1 = new Dictionary();
+ dict1.Add("a", "1");
+ dict1.Add("b", "2");
+ dict1.Add("c", "3");
+
+ var dict2 = new Dictionary();
+ dict2.Add("a", "1");
+ dict2.Add("b", "2");
+ dict2.Add("c", "3");
+
+ Assert.IsTrue(HostingServicesWindow.DictsAreEqual(dict1, dict2), "Two identically created dictionaries should be equal, but aren't.");
+ }
+
+ [Test]
+ public void DictsAreEqual_ReturnsFalseOnSameKeyDifVal()
+ {
+ var dict1 = new Dictionary();
+ dict1.Add("a", "x");
+ dict1.Add("b", "y");
+ dict1.Add("c", "z");
+
+ var dict2 = new Dictionary();
+ dict2.Add("a", "1");
+ dict2.Add("b", "2");
+ dict2.Add("c", "3");
+
+ Assert.IsFalse(HostingServicesWindow.DictsAreEqual(dict1, dict2), "Same keys with different values should not be considered equal.");
+ }
+
+ [Test]
+ public void DictsAreEqual_ReturnsFalseOnSameValDifKey()
+ {
+ var dict1 = new Dictionary();
+ dict1.Add("x", "1");
+ dict1.Add("y", "2");
+ dict1.Add("z", "3");
+
+ var dict2 = new Dictionary();
+ dict2.Add("a", "1");
+ dict2.Add("b", "2");
+ dict2.Add("c", "3");
+
+ Assert.IsFalse(HostingServicesWindow.DictsAreEqual(dict1, dict2), "Same values with different keys should not be considered equal.");
+ }
+
+
+ [Test]
+ public void DictsAreEqual_ReturnsFalseOnSubset()
+ {
+ var dict1 = new Dictionary();
+ dict1.Add("a", "1");
+ dict1.Add("b", "2");
+
+ var dict2 = new Dictionary();
+ dict2.Add("a", "1");
+ dict2.Add("b", "2");
+ dict2.Add("c", "3");
+
+ Assert.IsFalse(HostingServicesWindow.DictsAreEqual(dict1, dict2), "Subset should not be considered equal (smaller first case)");
+ Assert.IsFalse(HostingServicesWindow.DictsAreEqual(dict2, dict1), "Subset should not be considered equal (larger first case)");
+ }
+
+ [Test]
+ public void DictsAreEqual_ReturnsFalseOnTriviallyUnequal()
+ {
+ var dict1 = new Dictionary();
+ dict1.Add("a", "1");
+
+ var dict2 = new Dictionary();
+ dict2.Add("b", "2");
+
+ Assert.IsFalse(HostingServicesWindow.DictsAreEqual(dict1, dict2), "Should return false on trivially false case");
+ }
+ }
+}
diff --git a/Tests/Editor/HostingServices/HostingServicesWindowUtilitiesTests.cs.meta b/Tests/Editor/HostingServices/HostingServicesWindowUtilitiesTests.cs.meta
new file mode 100644
index 00000000..8c2f757b
--- /dev/null
+++ b/Tests/Editor/HostingServices/HostingServicesWindowUtilitiesTests.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c63ec1e574af01940b50bc1959310719
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Tests/Runtime/ResourceManager/OperationsCacheTests.cs b/Tests/Runtime/ResourceManager/OperationsCacheTests.cs
index 74b75ec2..0b78d4f2 100644
--- a/Tests/Runtime/ResourceManager/OperationsCacheTests.cs
+++ b/Tests/Runtime/ResourceManager/OperationsCacheTests.cs
@@ -81,5 +81,47 @@ public int Hash(Type type)
public string PrimaryKey { get; }
public Type ResourceType { get; }
}
+
+ [Test]
+ public void Locations_WithDiffNames_LocationEquals_Returns_True()
+ {
+ var l1 = new ResourceLocationBase("a", "b", "c", typeof(Mesh));
+ var l2 = new ResourceLocationBase("x", "b", "c", typeof(Mesh));
+ Assert.IsTrue(LocationUtils.LocationEquals(l1, l2));
+ }
+ [Test]
+ public void Locations_WithDiffIds_LocationEquals_Returns_False()
+ {
+ var l1 = new ResourceLocationBase("a", "b", "c", typeof(Mesh));
+ var l2 = new ResourceLocationBase("a", "x", "c", typeof(Mesh));
+ Assert.IsFalse(LocationUtils.LocationEquals(l1, l2));
+ }
+ [Test]
+ public void Locations_WithDiffProvider_LocationEquals_Returns_False()
+ {
+ var l1 = new ResourceLocationBase("a", "b", "c", typeof(Mesh));
+ var l2 = new ResourceLocationBase("a", "b", "x", typeof(Mesh));
+ Assert.IsFalse(LocationUtils.LocationEquals(l1, l2));
+ }
+ [Test]
+ public void Locations_WithDiffResourceTypes_LocationEquals_Returns_True()
+ {
+ var l1 = new ResourceLocationBase("a", "b", "c", typeof(Mesh));
+ var l2 = new ResourceLocationBase("a", "b", "c", typeof(Material));
+ Assert.IsFalse(LocationUtils.LocationEquals(l1, l2));
+ }
+
+ class ResourceLocatonTestSub : ResourceLocationBase
+ {
+ public ResourceLocatonTestSub(string n, string id, string pr, Type t) : base(n, id, pr, t) { }
+ }
+ [Test]
+ public void Locations_WithDiffTypes_LocationEquals_Returns_True()
+ {
+ var l1 = new ResourceLocationBase("a", "b", "c", typeof(Mesh));
+ var l2 = new ResourceLocatonTestSub("a", "b", "c", typeof(Mesh));
+ Assert.IsTrue(LocationUtils.LocationEquals(l1, l2));
+ }
+
}
}
diff --git a/ValidationExceptions.json b/ValidationExceptions.json
index a2ce9ff3..19dd3e82 100644
--- a/ValidationExceptions.json
+++ b/ValidationExceptions.json
@@ -4,7 +4,7 @@
{
"ValidationTest": "API Validation",
"ExceptionError": "",
- "PackageVersion": "1.18.13"
+ "PackageVersion": "1.18.15"
}
]
}
diff --git a/package.json b/package.json
index dc83b91f..62677e8e 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "com.unity.addressables",
"displayName": "Addressables",
- "version": "1.18.13",
+ "version": "1.18.15",
"unity": "2018.4",
"description": "The Addressable Asset System allows the developer to ask for an asset via its address. Once an asset (e.g. a prefab) is marked \"addressable\", it generates an address which can be called from anywhere. Wherever the asset resides (local or remote), the system will locate it and its dependencies, then return it.\n\nUse 'Window->Asset Management->Addressables' to begin working with the system.\n\nAddressables use asynchronous loading to support loading from any location with any collection of dependencies. Whether you have been using direct references, traditional asset bundles, or Resource folders, addressables provide a simpler way to make your game more dynamic. Addressables simultaneously opens up the world of asset bundles while managing all the complexity.\n\nFor usage samples, see github.com/Unity-Technologies/Addressables-Sample",
"keywords": [
@@ -22,10 +22,10 @@
"repository": {
"url": "https://github.cds.internal.unity3d.com/unity/Addressables.git",
"type": "git",
- "revision": "81df6d1c19bda49913cb4124a0a58a736bddb760"
+ "revision": "a47f367eb3d1a9824c6411750cbbcb8a6b4aabda"
},
"upmCi": {
- "footprint": "1cd1bd6a7a4fdbcc1453c7c2aa8a982e3b8b3bef"
+ "footprint": "e2b0f660313e0472439fb54a43cf935f7d069e3a"
},
"samples": [
{