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));
    }
Exemple #4
0
        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());
        }
Exemple #5
0
        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);
        }
Exemple #8
0
    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);
    }
Exemple #9
0
        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));
        }
Exemple #11
0
        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);
        }
Exemple #14
0
        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
        }
Exemple #16
0
        /// <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));
        }
Exemple #17
0
        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);
    }
Exemple #22
0
        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);
            }
        }
Exemple #25
0
        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));
        }
Exemple #26
0
        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);
                });
            }
        }
Exemple #27
0
        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);
        }
Exemple #28
0
        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);
        }