public void WhenPrefabContainsDuplicateTypes_GetSortedSceneObjectIdentifiers_DoesNotThorwError() { var includes = new List <ObjectIdentifier>(ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(k_TempGuid, EditorUserBuildSettings.activeBuildTarget)); var sorted = GenerateBundleCommands.GetSortedSceneObjectIdentifiers(includes); Assert.AreEqual(includes.Count, sorted.Count); }
internal void CreateCatalogEntriesInternal(List <ContentCatalogDataEntry> entries, bool isBundled, string providerType, IEnumerable <object> dependencies, object extraData, Dictionary <GUID, AssetLoadInfo> depInfo, HashSet <Type> providerTypes, bool includeAddress, bool includeGUID, bool includeLabels, HashSet <string> assetsInBundle) { if (string.IsNullOrEmpty(AssetPath)) { return; } string assetPath = GetAssetLoadPath(isBundled, assetsInBundle); List <object> keyList = CreateKeyList(includeAddress, includeGUID, includeLabels); if (keyList.Count == 0) { return; } //The asset may have previously been invalid. Since then, it may have been re-imported. //This can occur in particular when using ScriptedImporters with complex, multi-step behavior. //Double-check the type here in case the asset has been imported correctly after we cached its type. if (MainAssetType == typeof(DefaultAsset)) { m_cachedMainAssetType = null; } Type mainType = AddressableAssetUtility.MapEditorTypeToRuntimeType(MainAssetType, false); if ((mainType == null || mainType == typeof(DefaultAsset)) && !IsInResources) { var t = MainAssetType; Debug.LogWarningFormat("Type {0} is in editor assembly {1}. Asset location with internal id {2} will be stripped.", t.Name, t.Assembly.FullName, assetPath); return; } Type runtimeProvider = GetRuntimeProviderType(providerType, mainType); if (runtimeProvider != null) { providerTypes.Add(runtimeProvider); } if (!IsScene) { ObjectIdentifier[] ids = depInfo != null ? depInfo[new GUID(guid)].includedObjects.ToArray() : ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(new GUID(guid), EditorUserBuildSettings.activeBuildTarget); foreach (var t in GatherSubObjectTypes(ids, guid)) { entries.Add(new ContentCatalogDataEntry(t, assetPath, providerType, keyList, dependencies, extraData)); } } else if (mainType != null && mainType != typeof(DefaultAsset)) { entries.Add(new ContentCatalogDataEntry(mainType, assetPath, providerType, keyList, dependencies, extraData)); } }
public void BuildCacheUtility_GetSortedUniqueTypesForObjects_ReturnsUniqueAndSortedTypeArray() { var includes = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(k_TempGuid, EditorUserBuildSettings.activeBuildTarget); // Test prefab is created using 2 primitive cubes, one parented to the other, so the includes will in turn contain the sequence 2x: Type[] expectedTypes = new[] { typeof(GameObject), typeof(Transform), typeof(MeshFilter), typeof(MeshRenderer), typeof(BoxCollider) }; Array.Sort(expectedTypes, (x, y) => x.AssemblyQualifiedName.CompareTo(y.AssemblyQualifiedName)); var actualTypes = BuildCacheUtility.GetSortedUniqueTypesForObjects(includes); Assert.AreEqual(expectedTypes.Length * 2, includes.Length); Assert.AreEqual(expectedTypes.Length, actualTypes.Length); CollectionAssert.AreEqual(expectedTypes, actualTypes); }
internal void CreateCatalogEntriesInternal(List <ContentCatalogDataEntry> entries, bool isBundled, string providerType, IEnumerable <object> dependencies, object extraData, Dictionary <GUID, AssetLoadInfo> depInfo) { if (string.IsNullOrEmpty(AssetPath)) { return; } string assetPath = GetAssetLoadPath(isBundled); List <object> keyList = CreateKeyList(); Type mainType = AddressableAssetUtility.MapEditorTypeToRuntimeType(MainAssetType, false); if (mainType == null && !IsInResources) { var t = MainAssetType; Debug.LogWarningFormat("Type {0} is in editor assembly {1}. Asset location with internal id {2} will be stripped.", t.Name, t.Assembly.FullName, assetPath); return; } if (mainType != null) { entries.Add(new ContentCatalogDataEntry(mainType, assetPath, providerType, keyList, dependencies, extraData)); } if (!IsScene) { ObjectIdentifier[] ids = depInfo != null ? depInfo[new GUID(guid)].includedObjects.ToArray() : ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(new GUID(guid), EditorUserBuildSettings.activeBuildTarget); if (ids.Length > 1) { Type [] typesForObjs = ContentBuildInterface.GetTypeForObjects(ids); HashSet <Type> typesSeen = new HashSet <Type>(); typesSeen.Add(mainType); foreach (var objType in typesForObjs) { if (typeof(Component).IsAssignableFrom(objType)) { continue; } Type rtType = AddressableAssetUtility.MapEditorTypeToRuntimeType(objType, false); if (rtType != null && !typesSeen.Contains(rtType)) { entries.Add(new ContentCatalogDataEntry(rtType, assetPath, providerType, keyList, dependencies, extraData)); typesSeen.Add(rtType); } } } } }
/// <summary> /// 查找某个资源引用到的资源 /// </summary> /// <param name="typeDB">可以通过<see cref="EditorExtend.CompilePlayerScriptsUtility.CompileCurrentTargetTypeDB"/>获取</param> /// <param name="buildTarget">如果为NoTarget 则使用当前的平台</param> public static ObjectIdentifier[] SearchAssetDependenciesWithAssetGUID(string assetGUID, TypeDB typeDB = null, BuildTarget buildTarget = BuildTarget.NoTarget) { if (buildTarget == BuildTarget.NoTarget) { buildTarget = EditorUserBuildSettings.activeBuildTarget; } if (typeDB == null) { CompilePlayerScriptsUtility.GetOrCompileCurrentTargetTypeDB(false, out typeDB); } ObjectIdentifier[] assetIncludes = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(new GUID(assetGUID), buildTarget); return(ContentBuildInterface.GetPlayerDependenciesForObjects(assetIncludes, buildTarget, typeDB)); }
static AssetLoadInfo GetTestAssetLoadInfo() { GUID asset = new GUID(AssetDatabase.AssetPathToGUID(k_TestAsset)); ObjectIdentifier[] oId = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(asset, EditorUserBuildSettings.activeBuildTarget); AssetLoadInfo loadInfo = new AssetLoadInfo() { asset = asset, address = k_TestAsset, includedObjects = oId.ToList(), referencedObjects = new List <ObjectIdentifier>() }; return(loadInfo); }
internal void CreateCatalogEntriesInternal(List <ContentCatalogDataEntry> entries, bool isBundled, string providerType, IEnumerable <object> dependencies, object extraData, Dictionary <GUID, AssetLoadInfo> depInfo, HashSet <Type> providerTypes, bool includeAddress, bool includeGUID, bool includeLabels, HashSet <string> assetsInBundle) { if (string.IsNullOrEmpty(AssetPath)) { return; } string assetPath = GetAssetLoadPath(isBundled, assetsInBundle); List <object> keyList = CreateKeyList(includeAddress, includeGUID, includeLabels); if (keyList.Count == 0) { return; } Type mainType = AddressableAssetUtility.MapEditorTypeToRuntimeType(MainAssetType, false); if (mainType == null && !IsInResources) { var t = MainAssetType; Debug.LogWarningFormat("Type {0} is in editor assembly {1}. Asset location with internal id {2} will be stripped.", t.Name, t.Assembly.FullName, assetPath); return; } Type runtimeProvider = GetRuntimeProviderType(providerType, mainType); if (runtimeProvider != null) { providerTypes.Add(runtimeProvider); } if (!IsScene) { ObjectIdentifier[] ids = depInfo != null ? depInfo[new GUID(guid)].includedObjects.ToArray() : ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(new GUID(guid), EditorUserBuildSettings.activeBuildTarget); foreach (var t in GatherSubObjectTypes(ids, guid)) { entries.Add(new ContentCatalogDataEntry(t, assetPath, providerType, keyList, dependencies, extraData)); } } else if (mainType != null) { entries.Add(new ContentCatalogDataEntry(mainType, assetPath, providerType, keyList, dependencies, extraData)); } }
static void GatherEntryLocations(AddressableAssetEntry entry, Type type, IList <IResourceLocation> locations, AddressableAssetTree assetTree) { if (!string.IsNullOrEmpty(entry.address) && entry.address.Contains("[") && entry.address.Contains("]")) { Debug.LogErrorFormat("Address '{0}' cannot contain '[ ]'.", entry.address); return; } using (new AddressablesFileEnumerationScope(assetTree)) { entry.GatherAllAssets(null, true, true, false, e => { if (e.IsScene) { if (type == null || type == typeof(SceneInstance) || AddressableAssetUtility.MapEditorTypeToRuntimeType(e.MainAssetType, false) == type) { locations.Add(new ResourceLocationBase(e.address, e.AssetPath, typeof(SceneProvider).FullName, typeof(SceneInstance))); } } else if (type == null || type.IsAssignableFrom(e.MainAssetType)) { locations.Add(new ResourceLocationBase(e.address, e.AssetPath, typeof(AssetDatabaseProvider).FullName, e.MainAssetType)); return(true); } else { ObjectIdentifier[] ids = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(new GUID(e.guid), EditorUserBuildSettings.activeBuildTarget); if (ids.Length > 1) { foreach (var t in AddressableAssetEntry.GatherSubObjectTypes(ids, e.guid)) { if (type.IsAssignableFrom(t)) { locations.Add(new ResourceLocationBase(e.address, e.AssetPath, typeof(AssetDatabaseProvider).FullName, t)); } } return(true); } } return(false); }); } }
static IDependencyData GetDependencyData() { GUID guid; GUID.TryParse(AssetDatabase.AssetPathToGUID(k_CubePath), out guid); ObjectIdentifier[] oId = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(guid, EditorUserBuildSettings.activeBuildTarget); AssetLoadInfo loadInfo = new AssetLoadInfo() { asset = guid, address = k_CubePath, includedObjects = oId.ToList(), referencedObjects = oId.ToList() }; IDependencyData dep = new BuildDependencyData(); dep.AssetInfo.Add(guid, loadInfo); return(dep); }
static CachedInfo CalculateTargetCachedInfo(CacheEntry entry, BuildTarget target, TypeDB typeDB = null) { var cache = new BuildCache(); List <ObjectIdentifier> objects = new List <ObjectIdentifier>(); objects.AddRange(ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(entry.Guid, target)); objects.AddRange(ContentBuildInterface.GetPlayerDependenciesForObjects(objects.ToArray(), target, typeDB)); var cachedInfo = new CachedInfo(); cachedInfo.Asset = entry; cachedInfo.Data = new[] { objects }; // TODO: Handle built-in objects, might require some low level build changes like an option to ignore the hideFlags var dependencies = objects.Select(x => x.guid).Where(x => !x.Empty() && x != entry.Guid && x != k_UnityBuiltinResources).Distinct(); cachedInfo.Dependencies = dependencies.Select(cache.GetCacheEntry).ToArray(); // cache.SaveCachedData(new List<CachedInfo> { cachedInfo }); // TODO: Disabled because we have file contention as "Save" is async only with no wait functionality return(cachedInfo); }
public void BuildCacheUtility_GetMainTypeForObjects_ReturnsUniqueAndSortedTypeArray() { var includes = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(k_TempGuid, EditorUserBuildSettings.activeBuildTarget); // Test prefab is created using 2 primitive cubes, one parented to the other, so the includes will in turn contain the sequence: Type[] expectedTypes = new[] { typeof(GameObject), typeof(Transform), typeof(MeshFilter), typeof(MeshRenderer), typeof(BoxCollider), typeof(GameObject), typeof(Transform), typeof(MeshFilter), typeof(MeshRenderer), typeof(BoxCollider) }; // One catch, the ordering of the expected types is based on the order of includes which is in turn ordered by the local identifier in file. // Since we are generating the prefab as part of the test, and lfids generation is random, we don't know what order they will be returned in. // So sort both expected types lists and compare exact. Array.Sort(expectedTypes, (x, y) => x.AssemblyQualifiedName.CompareTo(y.AssemblyQualifiedName)); var actualTypes = BuildCacheUtility.GetMainTypeForObjects(includes); Array.Sort(actualTypes, (x, y) => x.AssemblyQualifiedName.CompareTo(y.AssemblyQualifiedName)); Assert.AreEqual(expectedTypes.Length, includes.Length); Assert.AreEqual(expectedTypes.Length, actualTypes.Length); CollectionAssert.AreEqual(expectedTypes, actualTypes); }
public void WhenAssetHasMultipleRepresentations_ExtendedDataContainsAllButMainAsset() { const int kExtraRepresentations = 2; string assetPath = Path.Combine(kTestAssetFolder, "myPrefab.asset"); Material mat = new Material(Shader.Find("Transparent/Diffuse")); AssetDatabase.CreateAsset(mat, assetPath); for (int i = 0; i < kExtraRepresentations; i++) { AssetDatabase.AddObjectToAsset(new Material(Shader.Find("Transparent/Diffuse")), assetPath); } AssetDatabase.SaveAssets(); GUID guid = new GUID(AssetDatabase.AssetPathToGUID(assetPath)); CalculateAssetDependencyData.TaskInput input = CreateDefaultInput(); input.Assets = new List <GUID>() { guid }; CalculateAssetDependencyData.RunInternal(input, out CalculateAssetDependencyData.TaskOutput output); ObjectIdentifier[] allObjIDs = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(guid, EditorUserBuildSettings.activeBuildTarget); HashSet <ObjectIdentifier> expectedReps = new HashSet <ObjectIdentifier>(); for (int i = 1; i < allObjIDs.Length; i++) { expectedReps.Add(allObjIDs[i]); } Assert.AreEqual(kExtraRepresentations, output.AssetResults[0].extendedData.Representations.Count); Assert.AreEqual(kExtraRepresentations, expectedReps.Count); foreach (var id in output.AssetResults[0].extendedData.Representations) { Assert.IsTrue(expectedReps.Contains(id)); } }
static unsafe NativeList <Hash128> ReferencedUnityObjectsToGUIDs(ReferencedUnityObjects referencedUnityObjects, AssetImportContext ctx) { var globalObjectIds = new GlobalObjectId[referencedUnityObjects.Array.Length]; var guids = new NativeList <Hash128>(globalObjectIds.Length, Allocator.Temp); GlobalObjectId.GetGlobalObjectIdsSlow(referencedUnityObjects.Array, globalObjectIds); for (int i = 0; i != globalObjectIds.Length; i++) { var assetGUID = globalObjectIds[i].assetGUID; // Skip most built-ins, except for BuiltInExtra which we need to depend on if (GUIDHelper.IsBuiltin(assetGUID)) { if (GUIDHelper.IsBuiltinExtraResources(assetGUID)) { var objectIdentifiers = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(assetGUID, ctx.selectedBuildTarget); foreach (var objectIdentifier in objectIdentifiers) { var packedGUID = assetGUID; GUIDHelper.PackBuiltinExtraWithFileIdent(ref packedGUID, objectIdentifier.localIdentifierInFile); guids.Add(packedGUID); } } else if (GUIDHelper.IsBuiltinResources(assetGUID)) { guids.Add(assetGUID); } } else if (!assetGUID.Empty()) { guids.Add(assetGUID); } } return(guids); }
static internal ReturnCode RunInternal(TaskInput input, out TaskOutput output) { input.EngineHooks = input.EngineHooks != null ? input.EngineHooks : new CalculateAssetDependencyHooks(); output = new TaskOutput(); output.AssetResults = new AssetOutput[input.Assets.Count]; IList <CachedInfo> cachedInfo = null; if (input.BuildCache != null) { IList <CacheEntry> entries = input.Assets.Select(x => input.BuildCache.GetCacheEntry(x, kVersion)).ToList(); input.BuildCache.LoadCachedData(entries, out cachedInfo); } for (int i = 0; i < input.Assets.Count; i++) { AssetOutput assetResult = new AssetOutput(); assetResult.asset = input.Assets[i]; if (cachedInfo != null && cachedInfo[i] != null) { assetResult.assetInfo = cachedInfo[i].Data[0] as AssetLoadInfo; assetResult.usageTags = cachedInfo[i].Data[1] as BuildUsageTagSet; assetResult.spriteData = cachedInfo[i].Data[2] as SpriteImporterData; assetResult.extendedData = cachedInfo[i].Data[3] as ExtendedAssetData; output.AssetResults[i] = assetResult; output.CachedAssetCount++; continue; } GUID asset = input.Assets[i]; string assetPath = AssetDatabase.GUIDToAssetPath(asset.ToString()); if (!input.ProgressTracker.UpdateInfoUnchecked(assetPath)) { return(ReturnCode.Canceled); } assetResult.assetInfo = new AssetLoadInfo(); assetResult.usageTags = new BuildUsageTagSet(); assetResult.assetInfo.asset = asset; var includedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(asset, input.Target); assetResult.assetInfo.includedObjects = new List <ObjectIdentifier>(includedObjects); var referencedObjects = ContentBuildInterface.GetPlayerDependenciesForObjects(includedObjects, input.Target, input.TypeDB); assetResult.assetInfo.referencedObjects = new List <ObjectIdentifier>(referencedObjects); var allObjects = new List <ObjectIdentifier>(includedObjects); allObjects.AddRange(referencedObjects); ContentBuildInterface.CalculateBuildUsageTags(allObjects.ToArray(), includedObjects, input.GlobalUsage, assetResult.usageTags, input.DependencyUsageCache); var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter; if (importer != null && importer.textureType == TextureImporterType.Sprite) { assetResult.spriteData = new SpriteImporterData(); assetResult.spriteData.PackedSprite = false; assetResult.spriteData.SourceTexture = includedObjects.First(); if (EditorSettings.spritePackerMode != SpritePackerMode.Disabled) { assetResult.spriteData.PackedSprite = referencedObjects.Length > 0; } #if !UNITY_2020_1_OR_NEWER if (EditorSettings.spritePackerMode == SpritePackerMode.AlwaysOn || EditorSettings.spritePackerMode == SpritePackerMode.BuildTimeOnly) { assetResult.spriteData.PackedSprite = !string.IsNullOrEmpty(importer.spritePackingTag); } #endif } var representations = input.EngineHooks.LoadAllAssetRepresentationsAtPath(assetPath); if (!representations.IsNullOrEmpty()) { assetResult.extendedData = new ExtendedAssetData(); for (int j = 0; j < representations.Length; j++) { if (representations[j] == null) { BuildLogger.LogWarning($"SubAsset {j} inside {assetPath} is null. It will not be included in the build."); continue; } if (AssetDatabase.IsMainAsset(representations[j])) { continue; } string guid; long localId; if (!AssetDatabase.TryGetGUIDAndLocalFileIdentifier(representations[j], out guid, out localId)) { continue; } assetResult.extendedData.Representations.AddRange(includedObjects.Where(x => x.localIdentifierInFile == localId)); } } output.AssetResults[i] = assetResult; } if (input.BuildCache != null) { List <CachedInfo> toCache = new List <CachedInfo>(); for (int i = 0; i < input.Assets.Count; i++) { AssetOutput r = output.AssetResults[i]; if (cachedInfo[i] == null) { toCache.Add(GetCachedInfo(input.BuildCache, input.Assets[i], r.assetInfo, r.usageTags, r.spriteData, r.extendedData)); } } input.BuildCache.SaveCachedData(toCache); } return(ReturnCode.Success); }
/// <inheritdoc /> public ReturnCode Run() { IList <CachedInfo> cachedInfo = null; IList <CachedInfo> uncachedInfo = null; if (m_Parameters.UseCache && m_Cache != null) { IList <CacheEntry> entries = m_Content.Scenes.Select(x => m_Cache.GetCacheEntry(x, Version)).ToList(); m_Cache.LoadCachedData(entries, out cachedInfo); uncachedInfo = new List <CachedInfo>(); } for (int i = 0; i < m_Content.Scenes.Count; i++) { GUID scene = m_Content.Scenes[i]; string scenePath = AssetDatabase.GUIDToAssetPath(scene.ToString()); SceneDependencyInfo sceneInfo; BuildUsageTagSet usageTags; if (cachedInfo != null && cachedInfo[i] != null) { if (!m_Tracker.UpdateInfoUnchecked(string.Format("{0} (Cached)", scenePath))) { return(ReturnCode.Canceled); } sceneInfo = (SceneDependencyInfo)cachedInfo[i].Data[0]; usageTags = cachedInfo[i].Data[1] as BuildUsageTagSet; } else { if (!m_Tracker.UpdateInfoUnchecked(scenePath)) { return(ReturnCode.Canceled); } var references = new HashSet <ObjectIdentifier>(); string[] dependencies = AssetDatabase.GetDependencies(scenePath); foreach (var assetPath in dependencies) { var assetGuid = new GUID(AssetDatabase.AssetPathToGUID(assetPath)); if (ValidationMethods.ValidAsset(assetGuid) != ValidationMethods.Status.Asset) { continue; } // TODO: Use Cache to speed this up? var assetIncludes = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(assetGuid, m_Parameters.Target); var assetReferences = ContentBuildInterface.GetPlayerDependenciesForObjects(assetIncludes, m_Parameters.Target, m_Parameters.ScriptInfo); references.UnionWith(assetIncludes); references.UnionWith(assetReferences); } sceneInfo = new SceneDependencyInfo(); usageTags = new BuildUsageTagSet(); sceneInfo.SetScene(scenePath); sceneInfo.SetProcessedScene(scenePath); sceneInfo.SetReferencedObjects(references.ToArray()); if (uncachedInfo != null) { uncachedInfo.Add(GetCachedInfo(scene, sceneInfo.referencedObjects, sceneInfo, usageTags)); } } SetOutputInformation(scene, sceneInfo, usageTags); } if (m_Parameters.UseCache && m_Cache != null) { m_Cache.SaveCachedData(uncachedInfo); } return(ReturnCode.Success); }
public ReturnCode Run() { var globalUsage = m_DependencyData.GlobalUsage; foreach (SceneDependencyInfo sceneInfo in m_DependencyData.SceneInfo.Values) { globalUsage |= sceneInfo.globalUsage; } if (m_SpriteData == null) { m_SpriteData = new BuildSpriteData(); } IList <CachedInfo> cachedInfo = null; List <CachedInfo> uncachedInfo = null; if (m_Parameters.UseCache && m_Cache != null) { IList <CacheEntry> entries = m_Content.Assets.Select(m_Cache.GetCacheEntry).ToList(); m_Cache.LoadCachedData(entries, out cachedInfo); uncachedInfo = new List <CachedInfo>(); } for (int i = 0; i < m_Content.Assets.Count; i++) { GUID asset = m_Content.Assets[i]; string assetPath = AssetDatabase.GUIDToAssetPath(asset.ToString()); AssetLoadInfo assetInfo; BuildUsageTagSet usageTags; SpriteImporterData importerData; if (cachedInfo != null && cachedInfo[i] != null) { if (!m_Tracker.UpdateInfoUnchecked(string.Format("{0} (Cached)", assetPath))) { return(ReturnCode.Canceled); } assetInfo = cachedInfo[i].Data[0] as AssetLoadInfo; usageTags = cachedInfo[i].Data[1] as BuildUsageTagSet; importerData = cachedInfo[i].Data[2] as SpriteImporterData; } else { if (!m_Tracker.UpdateInfoUnchecked(assetPath)) { return(ReturnCode.Canceled); } assetInfo = new AssetLoadInfo(); usageTags = new BuildUsageTagSet(); importerData = null; assetInfo.asset = asset; var includedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(asset, m_Parameters.Target); assetInfo.includedObjects = new List <ObjectIdentifier>(includedObjects); var referencedObjects = ContentBuildInterface.GetPlayerDependenciesForObjects(includedObjects, m_Parameters.Target, m_Parameters.ScriptInfo); assetInfo.referencedObjects = new List <ObjectIdentifier>(referencedObjects); ContentBuildInterface.CalculateBuildUsageTags(referencedObjects, includedObjects, globalUsage, usageTags, m_DependencyData.DependencyUsageCache); var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter; if (importer != null && importer.textureType == TextureImporterType.Sprite) { importerData = new SpriteImporterData(); importerData.PackedSprite = !string.IsNullOrEmpty(importer.spritePackingTag); importerData.SourceTexture = includedObjects.First(); } if (uncachedInfo != null) { uncachedInfo.Add(GetCachedInfo(asset, assetInfo, usageTags, importerData)); } } SetOutputInformation(asset, assetInfo, usageTags, importerData); } if (m_SpriteData.ImporterData.Count == 0) { m_SpriteData = null; } if (m_Parameters.UseCache && m_Cache != null) { m_Cache.SaveCachedData(uncachedInfo); } return(ReturnCode.Success); }
public bool Locate(object key, Type type, out IList <IResourceLocation> locations) { CacheKey cacheKey = new CacheKey() { m_key = key, m_type = type }; if (m_Cache.TryGetValue(cacheKey, out locations)) { return(locations != null); } locations = new List <IResourceLocation>(); if (m_keyToEntries.TryGetValue(key, out HashSet <AddressableAssetEntry> entries)) { foreach (AddressableAssetEntry e in entries) { if (AssetDatabase.IsValidFolder(e.AssetPath) && !e.labels.Contains(key as string)) { continue; } if (type == null) { if (e.MainAssetType != typeof(SceneAsset)) { ObjectIdentifier[] ids = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(new GUID(e.guid), EditorUserBuildSettings.activeBuildTarget); IEnumerable <Type> subObjectTypes = AddressableAssetEntry.GatherSubObjectTypes(ids, e.guid); if (subObjectTypes.Any()) { foreach (Type t in subObjectTypes) { GatherEntryLocations(e, t, locations, m_AddressableAssetTree); } } else { GatherEntryLocations(e, null, locations, m_AddressableAssetTree); } } else { GatherEntryLocations(e, null, locations, m_AddressableAssetTree); } } else { GatherEntryLocations(e, type, locations, m_AddressableAssetTree); } } } if (type == null) { type = typeof(UnityEngine.Object); } string keyStr = key as string; if (!string.IsNullOrEmpty(keyStr)) { //check if the key is a guid first var keyPath = AssetDatabase.GUIDToAssetPath(keyStr); if (!string.IsNullOrEmpty(keyPath)) { //only look for folders from GUID if no locations have been found if (locations.Count == 0) { var slash = keyPath.LastIndexOf('/'); while (slash > 0) { keyPath = keyPath.Substring(0, slash); var parentFolderKey = AssetDatabase.AssetPathToGUID(keyPath); if (string.IsNullOrEmpty(parentFolderKey)) { break; } if (m_keyToEntries.ContainsKey(parentFolderKey)) { AddLocations(locations, type, keyPath, AssetDatabase.GUIDToAssetPath(keyStr)); break; } slash = keyPath.LastIndexOf('/'); } } } else { //if the key is not a GUID, see if it is contained in a folder entry keyPath = keyStr; int slash = keyPath.LastIndexOf('/'); while (slash > 0) { keyPath = keyPath.Substring(0, slash); if (m_keyToEntries.TryGetValue(keyPath, out var entry)) { foreach (var e in entry) { AddLocations(locations, type, keyStr, GetInternalIdFromFolderEntry(keyStr, e)); } break; } slash = keyPath.LastIndexOf('/'); } } //check resources folders if (m_includeResourcesFolders) { string resPath = keyStr; UnityEngine.Object obj = Resources.Load(resPath, type); if (obj == null && keyStr.Length == 32) { resPath = AssetDatabase.GUIDToAssetPath(keyStr); if (!string.IsNullOrEmpty(resPath)) { int index = resPath.IndexOf("Resources/", StringComparison.Ordinal); if (index >= 0) { int start = index + 10; int length = resPath.Length - (start + System.IO.Path.GetExtension(resPath).Length); resPath = resPath.Substring(index + 10, length); obj = Resources.Load(resPath, type); } } } if (obj != null) { locations.Add(new ResourceLocationBase(keyStr, resPath, typeof(LegacyResourcesProvider).FullName, type)); } } } if (locations.Count == 0) { locations = null; m_Cache.Add(cacheKey, locations); return(false); } m_Cache.Add(cacheKey, locations); return(true); }
static internal ReturnCode RunInternal(TaskInput input, out TaskOutput output) { #if !UNITY_2020_2_OR_NEWER input.EngineHooks = input.EngineHooks != null ? input.EngineHooks : new CalculateAssetDependencyHooks(); #endif output = new TaskOutput(); output.AssetResults = new AssetOutput[input.Assets.Count]; IList <CachedInfo> cachedInfo = null; if (input.BuildCache != null) { IList <CacheEntry> entries = input.Assets.Select(x => input.BuildCache.GetCacheEntry(x, kVersion)).ToList(); input.BuildCache.LoadCachedData(entries, out cachedInfo); } using (input.Logger.ScopedStep(LogLevel.Info, "Calculate Dependencies")) { for (int i = 0; i < input.Assets.Count; i++) { AssetOutput assetResult = new AssetOutput(); assetResult.asset = input.Assets[i]; if (cachedInfo != null && cachedInfo[i] != null) { assetResult.assetInfo = cachedInfo[i].Data[0] as AssetLoadInfo; assetResult.usageTags = cachedInfo[i].Data[1] as BuildUsageTagSet; assetResult.spriteData = cachedInfo[i].Data[2] as SpriteImporterData; assetResult.extendedData = cachedInfo[i].Data[3] as ExtendedAssetData; assetResult.objectTypes = cachedInfo[i].Data[4] as List <KeyValuePair <ObjectIdentifier, System.Type[]> >; output.AssetResults[i] = assetResult; output.CachedAssetCount++; continue; } GUID asset = input.Assets[i]; string assetPath = AssetDatabase.GUIDToAssetPath(asset.ToString()); if (!input.ProgressTracker.UpdateInfoUnchecked(assetPath)) { return(ReturnCode.Canceled); } assetResult.assetInfo = new AssetLoadInfo(); assetResult.usageTags = new BuildUsageTagSet(); assetResult.assetInfo.asset = asset; var includedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(asset, input.Target); assetResult.assetInfo.includedObjects = new List <ObjectIdentifier>(includedObjects); var referencedObjects = ContentBuildInterface.GetPlayerDependenciesForObjects(includedObjects, input.Target, input.TypeDB); assetResult.assetInfo.referencedObjects = new List <ObjectIdentifier>(referencedObjects); var allObjects = new List <ObjectIdentifier>(includedObjects); allObjects.AddRange(referencedObjects); ContentBuildInterface.CalculateBuildUsageTags(allObjects.ToArray(), includedObjects, input.GlobalUsage, assetResult.usageTags, input.DependencyUsageCache); var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter; if (importer != null && importer.textureType == TextureImporterType.Sprite) { assetResult.spriteData = new SpriteImporterData(); assetResult.spriteData.PackedSprite = false; assetResult.spriteData.SourceTexture = includedObjects.FirstOrDefault(); if (EditorSettings.spritePackerMode != SpritePackerMode.Disabled) { assetResult.spriteData.PackedSprite = referencedObjects.Length > 0; } #if !UNITY_2020_1_OR_NEWER if (EditorSettings.spritePackerMode == SpritePackerMode.AlwaysOn || EditorSettings.spritePackerMode == SpritePackerMode.BuildTimeOnly) { assetResult.spriteData.PackedSprite = !string.IsNullOrEmpty(importer.spritePackingTag); } #endif } #if !UNITY_2020_2_OR_NEWER GatherAssetRepresentations(assetPath, input.EngineHooks.LoadAllAssetRepresentationsAtPath, includedObjects, out assetResult.extendedData); #else GatherAssetRepresentations(asset, input.Target, out assetResult.extendedData); #endif output.AssetResults[i] = assetResult; } } if (input.BuildCache != null) { List <CachedInfo> toCache = new List <CachedInfo>(); for (int i = 0; i < input.Assets.Count; i++) { AssetOutput r = output.AssetResults[i]; if (cachedInfo[i] == null) { toCache.Add(GetCachedInfo(input.BuildCache, input.Assets[i], r.assetInfo, r.usageTags, r.spriteData, r.extendedData)); } } input.BuildCache.SaveCachedData(toCache); } return(ReturnCode.Success); }
public void AddHashToBundleNameTask_DoesNotChangeHash_WhenAssetsChangeOrder() { //Setup string path1 = $"{TempPath}/test1.prefab"; string path2 = $"{TempPath}/test2.prefab"; string path3 = $"{TempPath}/test3.prefab"; GUID guid1 = new GUID(CreateAsset(path1, "1")); GUID guid2 = new GUID(CreateAsset(path2, "2")); GUID guid3 = new GUID(CreateAsset(path3, "3")); List <GUID> list1 = new List <GUID>() { guid1, guid2, guid3 }; List <GUID> list2 = new List <GUID>() { guid2, guid1, guid3 }; AddressableAssetGroup group = m_Settings.CreateGroup("AddHashTestGroup", false, false, false, new List <AddressableAssetGroupSchema>()); m_Settings.CreateOrMoveEntry(guid1.ToString(), group); m_Settings.CreateOrMoveEntry(guid2.ToString(), group); m_Settings.CreateOrMoveEntry(guid3.ToString(), group); IDependencyData dependencyData = new BuildDependencyData() { AssetInfo = { { guid1, new AssetLoadInfo() { referencedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(guid1, EditorUserBuildSettings.activeBuildTarget).ToList() } }, { guid2, new AssetLoadInfo() { referencedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(guid2, EditorUserBuildSettings.activeBuildTarget).ToList() } }, { guid3, new AssetLoadInfo() { referencedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(guid3, EditorUserBuildSettings.activeBuildTarget).ToList() } } } }; AddressableAssetsBuildContext context = new AddressableAssetsBuildContext() { Settings = m_Settings }; AddHashToBundleNameTask addHashTask = new AddHashToBundleNameTask(); var field = typeof(AddHashToBundleNameTask).GetField("m_DependencyData", BindingFlags.Instance | BindingFlags.NonPublic); field.SetValue(addHashTask, dependencyData); //Test RawHash hash1 = addHashTask.GetAssetsHash(list1, context); RawHash hash2 = addHashTask.GetAssetsHash(list2, context); //Assert Assert.AreEqual(hash1, hash2); //Cleanup m_Settings.RemoveGroup(group); }
public ReturnCode Run() { var globalUsage = m_DependencyData.GlobalUsage; foreach (SceneDependencyInfo sceneInfo in m_DependencyData.SceneInfo.Values) { globalUsage |= sceneInfo.globalUsage; } if (m_SpriteData == null) { m_SpriteData = new BuildSpriteData(); } if (m_ExtendedAssetData == null) { m_ExtendedAssetData = new BuildExtendedAssetData(); } IList <CachedInfo> cachedInfo = null; List <CachedInfo> uncachedInfo = null; if (m_Parameters.UseCache && m_Cache != null) { IList <CacheEntry> entries = m_Content.Assets.Select(x => m_Cache.GetCacheEntry(x, Version)).ToList(); m_Cache.LoadCachedData(entries, out cachedInfo); uncachedInfo = new List <CachedInfo>(); } for (int i = 0; i < m_Content.Assets.Count; i++) { GUID asset = m_Content.Assets[i]; string assetPath = AssetDatabase.GUIDToAssetPath(asset.ToString()); AssetLoadInfo assetInfo; BuildUsageTagSet usageTags; SpriteImporterData importerData; ExtendedAssetData assetData; if (cachedInfo != null && cachedInfo[i] != null) { if (!m_Tracker.UpdateInfoUnchecked(string.Format("{0} (Cached)", assetPath))) { return(ReturnCode.Canceled); } assetInfo = cachedInfo[i].Data[0] as AssetLoadInfo; usageTags = cachedInfo[i].Data[1] as BuildUsageTagSet; importerData = cachedInfo[i].Data[2] as SpriteImporterData; assetData = cachedInfo[i].Data[3] as ExtendedAssetData; } else { if (!m_Tracker.UpdateInfoUnchecked(assetPath)) { return(ReturnCode.Canceled); } assetInfo = new AssetLoadInfo(); usageTags = new BuildUsageTagSet(); importerData = null; assetData = null; assetInfo.asset = asset; var includedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(asset, m_Parameters.Target); assetInfo.includedObjects = new List <ObjectIdentifier>(includedObjects); var referencedObjects = ContentBuildInterface.GetPlayerDependenciesForObjects(includedObjects, m_Parameters.Target, m_Parameters.ScriptInfo); assetInfo.referencedObjects = new List <ObjectIdentifier>(referencedObjects); var allObjects = new List <ObjectIdentifier>(includedObjects); allObjects.AddRange(referencedObjects); ContentBuildInterface.CalculateBuildUsageTags(allObjects.ToArray(), includedObjects, globalUsage, usageTags, m_DependencyData.DependencyUsageCache); var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter; if (importer != null && importer.textureType == TextureImporterType.Sprite) { // Legacy Sprite Packing Modes if (EditorSettings.spritePackerMode == SpritePackerMode.AlwaysOn || EditorSettings.spritePackerMode == SpritePackerMode.BuildTimeOnly) { importerData = new SpriteImporterData(); importerData.PackedSprite = !string.IsNullOrEmpty(importer.spritePackingTag); importerData.SourceTexture = includedObjects.First(); } else if (!referencedObjects.IsNullOrEmpty()) // Sprite is referencing packed data { importerData = new SpriteImporterData(); importerData.PackedSprite = EditorSettings.spritePackerMode != SpritePackerMode.Disabled; importerData.SourceTexture = includedObjects.First(); } } var representations = AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath); if (!representations.IsNullOrEmpty()) { assetData = new ExtendedAssetData(); foreach (var representation in representations) { if (AssetDatabase.IsMainAsset(representation)) { continue; } string guid; long localId; if (!AssetDatabase.TryGetGUIDAndLocalFileIdentifier(representation, out guid, out localId)) { continue; } assetData.Representations.AddRange(includedObjects.Where(x => x.localIdentifierInFile == localId)); } } if (uncachedInfo != null) { uncachedInfo.Add(GetCachedInfo(asset, assetInfo, usageTags, importerData, assetData)); } } SetOutputInformation(asset, assetInfo, usageTags, importerData, assetData); } if (m_SpriteData.ImporterData.Count == 0) { m_SpriteData = null; } if (m_ExtendedAssetData.ExtendedData.Count == 0) { m_SpriteData = null; } if (m_Parameters.UseCache && m_Cache != null) { m_Cache.SaveCachedData(uncachedInfo); } return(ReturnCode.Success); }