public static void Build() { ReadCommandLine(); if (Directory.Exists(folderPath)) { Directory.Delete(folderPath, true); } if (Directory.Exists(k_TmpPath)) { Directory.Delete(k_TmpPath, true); } Directory.CreateDirectory(folderPath); Directory.CreateDirectory(k_TmpPath); IBundleBuildParameters buildParams = new BundleBuildParameters(EditorUserBuildSettings.activeBuildTarget, BuildTargetGroup.Unknown, folderPath); buildParams.TempOutputFolder = k_TmpPath; IBundleBuildContent buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds()); IBundleBuildResults results; List <IBuildTask> taskList = DefaultBuildTasks.Create(DefaultBuildTasks.Preset.AssetBundleBuiltInShaderExtraction) as List <IBuildTask>; taskList.Add(new RefreshAssetDatabase()); // we add a callback after generating information about how to build each bundle ContentPipeline.BuildCallbacks.PostPackingCallback += PostPackingCallback; ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results, taskList); Debug.Log("Building completed with " + exitCode); }
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); }
/// <summary> /// The BundleBuildContent class contains information about all of the Assets you want to build into the BuildMap /// Assets are referenced to by a GUID object, and the Addresses can be obtained and modified by using a GUID to /// refer to each asset and identify its Address /// </summary> /// <param name="outputPath"></param> /// <param name="compressionMode"></param> /// <param name="buildTarget"></param> /// <param name="buildGroup"></param> /// <param name="results"></param> /// <returns></returns> public static ReturnCode BuildAssetBundles(string outputPath, CompressionType compressionMode, BuildTarget buildTarget, BuildTargetGroup buildGroup, out IBundleBuildResults results) { BundleBuildContent buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds()); // Go through assets content and set their address to its filename for (int i = 0; i < buildContent.Assets.Count; ++i) { GUID g = buildContent.Assets[i]; // Get the current address as the full filepath and change it to just be the filename buildContent.Addresses[g] = Path.GetFileNameWithoutExtension(buildContent.Addresses[g]); } BundleBuildParameters buildParams = new BundleBuildParameters(buildTarget, buildGroup, outputPath); switch (compressionMode) { case CompressionType.None: buildParams.BundleCompression = BuildCompression.Uncompressed; break; case CompressionType.Lz4: buildParams.BundleCompression = BuildCompression.LZ4; break; default: buildParams.BundleCompression = BuildCompression.LZMA; break; } return(ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results)); }
public static ObjectIdentifier[] FilterReferencedObjectIDs(GUID asset, ObjectIdentifier[] references, BuildTarget target, TypeDB typeDB, HashSet <GUID> dependencies) { // Expectation: references is populated with DependencyType.ValidReferences only for the given asset var collectedImmediateReferences = new HashSet <ObjectIdentifier>(); var encounteredDependencies = new HashSet <ObjectIdentifier>(); while (references.Length > 0) { // Track which roots we encounter to do dependency pruning encounteredDependencies.UnionWith(references.Where(x => x.guid != asset && dependencies.Contains(x.guid))); // We only want to recursively grab references for objects being pulled in and won't go to another bundle ObjectIdentifier[] immediateReferencesNotInOtherBundles = references.Where(x => !dependencies.Contains(x.guid) && !collectedImmediateReferences.Contains(x)).ToArray(); collectedImmediateReferences.UnionWith(immediateReferencesNotInOtherBundles); // Grab next set of valid references and loop references = ContentBuildInterface.GetPlayerDependenciesForObjects(immediateReferencesNotInOtherBundles, target, typeDB, DependencyType.ValidReferences); } // We need to ensure that we have a reference to a visible representation so our runtime dependency appending process // can find something that can be appended, otherwise the necessary data will fail to load correctly in all cases. (EX: prefab A has reference to component on prefab B) foreach (var dependency in encounteredDependencies) { // For each dependency, add just the main representation as a reference var representations = ContentBuildInterface.GetPlayerAssetRepresentations(dependency.guid, target); collectedImmediateReferences.Add(representations.First()); } collectedImmediateReferences.UnionWith(encounteredDependencies); return(collectedImmediateReferences.ToArray()); }
public static void Build(Setting setting) { if (setting == null) { return; } var path = setting.BuildInfo.OutputPath; if (!Path.IsPathRooted(path)) { path = Path.GetFullPath(Path.Combine(Application.dataPath, "..", path)); } var buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds()); var buildParam = new BundleBuildParameters(setting.BuildInfo.Target, setting.BuildInfo.TargetGroup, path); buildParam.ScriptOptions = ScriptCompilationOptions.None; buildParam.BundleCompression = UnityEngine.BuildCompression.LZ4; var settingContext = new LibCraftopiaSetting(setting); var tasks = BuildPipeline.CreatPipeline(); var code = ContentPipeline.BuildAssetBundles(buildParam, buildContent, out var result, tasks, settingContext); if (code < 0) { UnityEngine.Debug.LogError("Build failed"); } }
/// <summary> /// Using the Compatible code path, this setup is limited to be the same as legacy pipeline. /// With this setup an array of content for each AssetBundle is passed into the pipeline. /// ContentBuildInterface.GeneratAssetBundleBuilds can be used to get an array for the bundleNames /// set in the AssetImporters in your project (as seen at the bottom of the inspector when selecting an asset) /// There are two arrays, /// .assetNames which contains the fullpath to the Asset to be included /// .addressableNames which is the string used when loading the Asset. /// These are connected by index, so assigning .addressableNames[8] = "Robo" is assigning the asset at .assetNames[8] /// to load via AssetBundle.LoadAsset<T>( "Robo" ); /// </summary> /// <param name="outputPath"></param> /// <param name="forceRebuild"></param> /// <param name="compression"></param> /// <param name="buildTarget"></param> /// <returns></returns> public static bool BuildCompatibilityAssetBundles(string outputPath, bool forceRebuild, CompressionType compression, BuildTarget buildTarget) { var options = BuildAssetBundleOptions.None; switch (compression) { case CompressionType.None: options |= BuildAssetBundleOptions.UncompressedAssetBundle; break; case CompressionType.Lz4: options |= BuildAssetBundleOptions.ChunkBasedCompression; break; } if (forceRebuild) { options |= BuildAssetBundleOptions.ForceRebuildAssetBundle; } AssetBundleBuild[] bundles = ContentBuildInterface.GenerateAssetBundleBuilds(); // go through each asset in the bundle and assign the addressable name to filename for (int i = 0; i < bundles.Length; i++) { bundles[i].addressableNames = bundles[i].assetNames.Select(Path.GetFileNameWithoutExtension).ToArray(); } var manifest = CompatibilityBuildPipeline.BuildAssetBundles(outputPath, bundles, options, buildTarget); return(manifest != null); }
public void CreateAssetEntryForObjectIdentifiers(ObjectIdentifier[] includedObjects, string path, string bundleName, string address, Type mainAssetType) { AssetLoadInfo assetInfo = new AssetLoadInfo(); BuildUsageTagSet usageTags = new BuildUsageTagSet(); assetInfo.asset = HashingMethods.Calculate(address).ToGUID(); if (m_DependencyData.AssetInfo.ContainsKey(assetInfo.asset)) { throw new ArgumentException(string.Format("Custom Asset '{0}' already exists. Building duplicate asset entries is not supported.", address)); } 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, m_GlobalUsage, usageTags, m_DependencyData.DependencyUsageCache); List <GUID> assets; m_Content.BundleLayout.GetOrAdd(bundleName, out assets); assets.Add(assetInfo.asset); m_Content.Addresses[assetInfo.asset] = address; m_Content.FakeAssets[assetInfo.asset] = path; SetOutputInformation(assetInfo.asset, assetInfo, usageTags); }
public static void Build() { if (Directory.Exists(folderPath)) { Directory.Delete(folderPath, true); } if (Directory.Exists(k_TmpPath)) { Directory.Delete(k_TmpPath, true); } Directory.CreateDirectory(folderPath); Directory.CreateDirectory(k_TmpPath); IBundleBuildParameters buildParams = new BundleBuildParameters(EditorUserBuildSettings.activeBuildTarget, BuildTargetGroup.Unknown, folderPath); buildParams.TempOutputFolder = k_TmpPath; IBundleBuildContent buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds()); IBundleBuildResults results; List <IBuildTask> taskList = DefaultBuildTasks.Create(DefaultBuildTasks.Preset.AssetBundleBuiltInShaderExtraction) as List <IBuildTask>; taskList.Add(new RefreshAssetDatabase()); taskList.Add(new CreateBuiltTimeReport()); ReturnCode exitCode = ContentPipelineProfiled.BuildAssetBundles(buildParams, buildContent, out results, taskList, new Profiler("Total")); Debug.Log("Building completed with " + exitCode); }
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)); } }
static internal void GatherAssetRepresentations(GUID asset, BuildTarget target, out ExtendedAssetData extendedData) { extendedData = null; ObjectIdentifier[] representations = ContentBuildInterface.GetPlayerAssetRepresentations(asset, target); // Main Asset always returns at index 0, we only want representations, so check for greater than 1 length if (representations.IsNullOrEmpty() || representations.Length < 2) { return; } extendedData = new ExtendedAssetData(); extendedData.Representations.AddRange(representations.Skip(1)); }
void GatherAssetData(string path, out AssetLoadInfo assetInfo, out BuildUsageTagSet buildUsage, BuildUsageTagGlobal globalUsage) { assetInfo = new AssetLoadInfo(); buildUsage = new BuildUsageTagSet(); var includedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInSerializedFile(path, m_Parameters.Target); var referencedObjects = ContentBuildInterface.GetPlayerDependenciesForObjects(includedObjects, m_Parameters.Target, m_Parameters.ScriptInfo); assetInfo.includedObjects = new List <ObjectIdentifier>(includedObjects); assetInfo.referencedObjects = new List <ObjectIdentifier>(referencedObjects); ContentBuildInterface.CalculateBuildUsageTags(referencedObjects, includedObjects, globalUsage, buildUsage, m_DependencyData.DependencyUsageCache); }
static List <ObjectIdentifier> GetSortedSceneObjectIdentifiers(List <ObjectIdentifier> objects) { var types = new List <Type>(ContentBuildInterface.GetTypeForObjects(objects.ToArray())); var sortedObjects = new List <SortObject>(); for (int i = 0; i < objects.Count; i++) { sortedObjects.Add(new SortObject { sortIndex = GetSortIndex(types[i]), objectId = objects[i] }); } return(sortedObjects.OrderBy(x => x.sortIndex).Select(x => x.objectId).ToList()); }
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); } } } } }
/// <inheritdoc /> public WriteResult Write(string outputFolder, BuildSettings settings, BuildUsageTagGlobal globalUsage) { #if UNITY_2019_3_OR_NEWER return(ContentBuildInterface.WriteSerializedFile(outputFolder, new WriteParameters { writeCommand = Command, settings = settings, globalUsage = globalUsage, usageSet = UsageSet, referenceMap = ReferenceMap })); #else return(ContentBuildInterface.WriteSerializedFile(outputFolder, Command, settings, globalUsage, UsageSet, ReferenceMap)); #endif }
/// <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); }
static private void ArchiveSingleItem(ArchiveWorkItem item, Dictionary <string, ulong> fileOffsets, string tempOutputFolder) { item.ResultDetails = new BundleDetails(); string writePath = string.Format("{0}/{1}", tempOutputFolder, item.BundleName); if (!string.IsNullOrEmpty(item.CachedArtifactPath)) { writePath = item.CachedArtifactPath; } Directory.CreateDirectory(Path.GetDirectoryName(writePath)); item.ResultDetails.FileName = item.OutputFilePath; item.ResultDetails.Crc = ContentBuildInterface.ArchiveAndCompress(item.ResourceFiles, writePath, item.Compression); item.ResultHash = CalculateHashVersion(fileOffsets, item.ResourceFiles, item.ResultDetails.Dependencies); CopyToOutputLocation(writePath, item.ResultDetails.FileName); }
/// <inheritdoc /> public WriteResult Write(string outputFolder, BuildSettings settings, BuildUsageTagGlobal globalUsage) { #if UNITY_2019_3_OR_NEWER return(ContentBuildInterface.WriteSceneSerializedFile(outputFolder, new WriteSceneParameters { scenePath = Scene, writeCommand = Command, settings = settings, globalUsage = globalUsage, usageSet = UsageSet, referenceMap = ReferenceMap, preloadInfo = PreloadInfo })); #else return(ContentBuildInterface.WriteSceneSerializedFile(outputFolder, Scene, ProcessedScene, Command, settings, globalUsage, UsageSet, ReferenceMap, PreloadInfo)); #endif }
public void Dispose() { ContentBuildProfileEvent[] events = ContentBuildInterface.StopProfileCapture(); if (m_Logger == null) { return; } IDeferredBuildLogger dLog = (IDeferredBuildLogger)m_Logger; IEnumerable <DeferredEvent> dEvents = events.Select(i => new DeferredEvent() { Level = LogLevel.Verbose, Name = i.Name, Time = (double)i.TimeMicroseconds / (double)1000, Type = BuildLoggerExternsions.ConvertToDeferredType(i.Type) }); dLog.HandleDeferredEventStream(dEvents); }
public static void Build() { var buildContent = new BundleBuildContent(ContentBuildInterface.GenerateAssetBundleBuilds()); var buildParams = new CustomBuildParameters(EditorUserBuildSettings.activeBuildTarget, EditorUserBuildSettings.selectedBuildTargetGroup, "Assets/StreamingAssets"); // set three different Assetbundles to be the different compression options available buildParams.m_PerBundleCompression.Add("textures", BuildCompression.LZMA); buildParams.m_PerBundleCompression.Add("objects", BuildCompression.LZ4); buildParams.m_PerBundleCompression.Add("prefabs", BuildCompression.Uncompressed); buildParams.BundleCompression = BuildCompression.LZMA; IBundleBuildResults results; ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParams, buildContent, out results); Debug.Log("Building per bundle completed with " + exitCode); }
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 private void ArchiveSingleItem(ArchiveWorkItem item, string tempOutputFolder, IBuildLogger log) { using (log.ScopedStep(LogLevel.Info, "ArchiveSingleItem", item.BundleName)) { item.ResultDetails = new BundleDetails(); string writePath = string.Format("{0}/{1}", tempOutputFolder, item.BundleName); if (!string.IsNullOrEmpty(item.CachedArtifactPath)) { writePath = item.CachedArtifactPath; } Directory.CreateDirectory(Path.GetDirectoryName(writePath)); item.ResultDetails.FileName = item.OutputFilePath; item.ResultDetails.Crc = ContentBuildInterface.ArchiveAndCompress(item.ResourceFiles.ToArray(), writePath, item.Compression); CopyFileWithTimestampIfDifferent(writePath, item.ResultDetails.FileName, log); } }
static private void ArchiveSingleItem(ArchiveWorkItem item, Dictionary <string, ulong> fileOffsets, string tempOutputFolder, IBuildLogger log) { using (log.ScopedStep(LogLevel.Info, $"Archive {item.BundleName}")) { item.ResultDetails = new BundleDetails(); string writePath = string.Format("{0}/{1}", tempOutputFolder, item.BundleName); if (!string.IsNullOrEmpty(item.CachedArtifactPath)) { writePath = item.CachedArtifactPath; } Directory.CreateDirectory(Path.GetDirectoryName(writePath)); item.ResultDetails.FileName = item.OutputFilePath; item.ResultDetails.Crc = ContentBuildInterface.ArchiveAndCompress(item.ResourceFiles, writePath, item.Compression); item.ResultHash = CalculateHashVersion(fileOffsets, item.ResourceFiles, item.ResultDetails.Dependencies); CopyFileWithTimestampIfDifferent(writePath, item.ResultDetails.FileName, log); } }
static internal void GatherAssetRepresentations(GUID asset, BuildTarget target, ObjectIdentifier[] includedObjects, out ExtendedAssetData extendedData) { extendedData = null; var includeSet = new HashSet <ObjectIdentifier>(includedObjects); // GetPlayerAssetRepresentations can return editor only objects, filter out those to only include what is in includedObjects ObjectIdentifier[] representations = ContentBuildInterface.GetPlayerAssetRepresentations(asset, target); var filteredRepresentations = representations.Where(includeSet.Contains); // Main Asset always returns at index 0, we only want representations, so check for greater than 1 length if (representations.IsNullOrEmpty() || filteredRepresentations.Count() < 2) { return; } extendedData = new ExtendedAssetData(); extendedData.Representations.AddRange(filteredRepresentations.Skip(1)); }
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 ReturnCode Run() { HashSet <ObjectIdentifier> buildInObjects = new HashSet <ObjectIdentifier>(); foreach (AssetLoadInfo dependencyInfo in m_DependencyData.AssetInfo.Values) { buildInObjects.UnionWith(dependencyInfo.referencedObjects.Where(x => x.guid == k_BuiltInGuid)); } foreach (SceneDependencyInfo dependencyInfo in m_DependencyData.SceneInfo.Values) { buildInObjects.UnionWith(dependencyInfo.referencedObjects.Where(x => x.guid == k_BuiltInGuid)); } ObjectIdentifier[] usedSet = buildInObjects.ToArray(); Type[] usedTypes = ContentBuildInterface.GetTypeForObjects(usedSet); if (m_Layout == null) { m_Layout = new BundleExplictObjectLayout(); } Type shader = typeof(Shader); for (int i = 0; i < usedTypes.Length; i++) { if (usedTypes[i] != shader) { continue; } m_Layout.ExplicitObjectLocation.Add(usedSet[i], ShaderBundleName); } if (m_Layout.ExplicitObjectLocation.Count == 0) { m_Layout = null; } return(ReturnCode.Success); }