コード例 #1
0
        private void WriteSerialziedFiles(string bundleName, IWriteOperation op, List <WriteCommand> allCommands, BuildSettings settings, BuildUsageTagGlobal globalUsage, ref List <WriteResult> outResults)
        {
            WriteResult result;
            var         dependencies = op.CalculateDependencies(allCommands);

            var objectIDs    = op.command.serializeObjects.Select(x => x.serializationObject).ToArray();
            var dependentIDs = dependencies.SelectMany(x => x.serializeObjects.Select(y => y.serializationObject)).ToArray();

            BuildUsageTagSet buildUsage = new BuildUsageTagSet();

            BundleBuildInterface.CalculateBuildUsageTags(objectIDs, dependentIDs, globalUsage, buildUsage);

            Hash128 hash = CalculateInputHash(op, dependencies, settings, globalUsage, buildUsage);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out result))
            {
                outResults.Add(result);
                return;
            }

            result = op.Write(GetBuildPath(hash), dependencies, settings, globalUsage, buildUsage);
            outResults.Add(result);

            if (UseCache && !BuildCache.SaveCachedResults(hash, result))
            {
                BuildLogger.LogWarning("Unable to cache CommandSetWriter results for command '{0}'.", op.command.internalName);
            }
        }
        public override BuildPipelineCodes Convert(AssetBundleBuild[] input, out BuildInput output)
        {
            StartProgressBar(input);

            // If enabled, try loading from cache
            var hash = CalculateInputHash(input);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out output))
            {
                EndProgressBar();
                return(BuildPipelineCodes.SuccessCached);
            }

            // Convert inputs
            output = new BuildInput();

            if (input.IsNullOrEmpty())
            {
                BuildLogger.LogError("Unable to continue packing. Input is null or empty!");
                EndProgressBar();
                return(BuildPipelineCodes.Error);
            }

            output.definitions = new BuildInput.Definition[input.Length];
            for (var i = 0; i < input.Length; i++)
            {
                output.definitions[i].assetBundleName = input[i].assetBundleName;
                output.definitions[i].explicitAssets  = new AssetIdentifier[input[i].assetNames.Length];
                for (var j = 0; j < input.Length; j++)
                {
                    UpdateProgressBar(input[i].assetNames[j]);
                    var guid = AssetDatabase.AssetPathToGUID(input[i].assetNames[j]);
                    output.definitions[i].explicitAssets[j].asset = new GUID(guid);
                    if (input[i].addressableNames.IsNullOrEmpty() || input[i].addressableNames.Length <= j || string.IsNullOrEmpty(input[i].addressableNames[j]))
                    {
                        output.definitions[i].explicitAssets[j].address = input[i].assetNames[j];
                    }
                    else
                    {
                        output.definitions[i].explicitAssets[j].address = input[i].addressableNames[j];
                    }
                }
            }

            // Cache results
            if (UseCache && !BuildCache.SaveCachedResults(hash, output))
            {
                BuildLogger.LogWarning("Unable to cache AssetBundleBuildConverter results.");
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }
コード例 #3
0
        public override BuildPipelineCodes Convert(GUID asset, BuildSettings settings, out AssetLoadInfo output)
        {
            StartProgressBar("Calculating Asset Dependencies", 2);

            if (!ValidAsset(asset))
            {
                output = new AssetLoadInfo();
                EndProgressBar();
                return(BuildPipelineCodes.Error);
            }

            Hash128 hash = CalculateInputHash(asset, settings);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out output))
            {
                if (!EndProgressBar())
                {
                    return(BuildPipelineCodes.Canceled);
                }
                return(BuildPipelineCodes.SuccessCached);
            }

            output       = new AssetLoadInfo();
            output.asset = asset;

            if (!UpdateProgressBar("Calculating included objects"))
            {
                EndProgressBar();
                return(BuildPipelineCodes.Canceled);
            }
            output.includedObjects = new List <ObjectIdentifier>(BundleBuildInterface.GetPlayerObjectIdentifiersInAsset(asset, settings.target));

            if (!UpdateProgressBar("Calculating referenced objects"))
            {
                EndProgressBar();
                return(BuildPipelineCodes.Canceled);
            }
            output.referencedObjects = new List <ObjectIdentifier>(BundleBuildInterface.GetPlayerDependenciesForObjects(output.includedObjects.ToArray(), settings.target, settings.typeDB));

            if (UseCache && !BuildCache.SaveCachedResults(hash, output))
            {
                BuildLogger.LogWarning("Unable to cache AssetDependency results for asset '{0}'.", asset);
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }
コード例 #4
0
        public override BuildPipelineCodes Convert(BuildDependencyInfo buildInfo, out BuildWriteInfo writeInfo)
        {
            StartProgressBar("Generating Build Commands", buildInfo.bundleToAssets.Count);

            Hash128 hash = CalculateInputHash(buildInfo);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out writeInfo))
            {
                writeInfo = new BuildWriteInfo();
                EndProgressBar();
                return(BuildPipelineCodes.SuccessCached);
            }

            writeInfo = new BuildWriteInfo();
            foreach (var bundle in buildInfo.bundleToAssets)
            {
                if (!UpdateProgressBar("Generating Build Commands"))
                {
                    return(BuildPipelineCodes.Canceled);
                }

                // TODO: Handle Player Data & Raw write formats
                if (IsAssetBundle(bundle.Value))
                {
                    var op = CreateAssetBundleWriteOperation(bundle.Key, bundle.Value, buildInfo);
                    writeInfo.assetBundles.Add(bundle.Key, op);
                }
                else if (IsSceneBundle(bundle.Value))
                {
                    var ops = CreateSceneBundleWriteOperations(bundle.Key, bundle.Value, buildInfo);
                    writeInfo.sceneBundles.Add(bundle.Key, ops);
                }
                else
                {
                    BuildLogger.LogError("Bundle '{0}' contains mixed assets and scenes.", bundle.Key);
                }
            }

            if (UseCache && !BuildCache.SaveCachedResults(hash, writeInfo))
            {
                BuildLogger.LogWarning("Unable to cache CommandSetProcessor results.");
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }
コード例 #5
0
        public override BuildPipelineCodes Convert(GUID scene, BuildSettings settings, BuildUsageTagSet usageSet, out SceneDependencyInfo output)
        {
            StartProgressBar("Calculating Scene Dependencies", 1);
            if (!ValidScene(scene))
            {
                output = new SceneDependencyInfo();
                EndProgressBar();
                return(BuildPipelineCodes.Error);
            }

            var scenePath = AssetDatabase.GUIDToAssetPath(scene.ToString());

            if (!UpdateProgressBar(scenePath))
            {
                output = new SceneDependencyInfo();
                EndProgressBar();
                return(BuildPipelineCodes.Canceled);
            }

            Hash128 hash = CalculateInputHash(scene, settings);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out output) && BuildCache.TryLoadCachedResults(hash, out usageSet))
            {
                if (!EndProgressBar())
                {
                    return(BuildPipelineCodes.Canceled);
                }
                return(BuildPipelineCodes.SuccessCached);
            }

            output = BundleBuildInterface.PrepareScene(scenePath, settings, usageSet, GetBuildPath(hash));

            if (UseCache && !BuildCache.SaveCachedResults(hash, output) && !BuildCache.SaveCachedResults(hash, usageSet))
            {
                BuildLogger.LogWarning("Unable to cache SceneDependency results for asset '{0}'.", scene);
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }
コード例 #6
0
        public override BuildPipelineCodes Convert(BuildCommandSet commandSet, BuildSettings settings, out List <WriteResult> output)
        {
            StartProgressBar("Writing Resource Files", commandSet.commands.Count);
            CacheDataForCommandSet(commandSet);

            output = new List <WriteResult>();
            foreach (var command in commandSet.commands)
            {
                if (!UpdateProgressBar(string.Format("Bundle: {0}", command.assetBundleName)))
                {
                    EndProgressBar();
                    return(BuildPipelineCodes.Canceled);
                }

                BuildOutput result;
                Hash128     hash = CalculateInputHash(command, settings);
                if (UseCache && BuildCache.TryLoadCachedResults(hash, out result))
                {
                    output.AddRange(result.results);
                    continue;
                }

                result = BundleBuildInterface.WriteResourceFilesForBundle(commandSet, command.assetBundleName, settings, GetBuildPath(hash));
                output.AddRange(result.results);

                if (UseCache && !BuildCache.SaveCachedResults(hash, result))
                {
                    BuildLogger.LogWarning("Unable to cache CommandSetWriter results for command '{0}'.", command.assetBundleName);
                }
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }
コード例 #7
0
        public override BuildPipelineCodes Convert(BuildDependencyInformation buildInfo, out BuildCommandSet output)
        {
            StartProgressBar("Generating Build Commands", buildInfo.assetLoadInfo.Count);

            Hash128 hash = CalculateInputHash(buildInfo);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out output))
            {
                output = new BuildCommandSet();
                EndProgressBar();
                return(BuildPipelineCodes.SuccessCached);
            }

            var commands = new List <BuildCommandSet.Command>();

            foreach (var bundle in buildInfo.bundleToAssets)
            {
                var command            = new BuildCommandSet.Command();
                var explicitAssets     = new List <BuildCommandSet.AssetLoadInfo>();
                var assetBundleObjects = new List <BuildCommandSet.SerializationInfo>();
                var dependencies       = new HashSet <string>();

                foreach (var asset in bundle.Value)
                {
                    var assetInfo = buildInfo.assetLoadInfo[asset];
                    explicitAssets.Add(assetInfo);
                    if (!UpdateProgressBar(assetInfo.asset))
                    {
                        output = new BuildCommandSet();
                        EndProgressBar();
                        return(BuildPipelineCodes.Canceled);
                    }

                    dependencies.UnionWith(buildInfo.assetToBundles[asset]);

                    foreach (var includedObject in assetInfo.includedObjects)
                    {
                        if (!buildInfo.virtualAssets.Contains(asset) && buildInfo.objectToVirtualAsset.ContainsKey(includedObject))
                        {
                            continue;
                        }

                        assetBundleObjects.Add(new BuildCommandSet.SerializationInfo
                        {
                            serializationObject = includedObject,
                            serializationIndex  = SerializationIndexFromObjectIdentifier(includedObject)
                        });
                    }

                    foreach (var referencedObject in assetInfo.referencedObjects)
                    {
                        if (referencedObject.filePath == kUnityDefaultResourcePath)
                        {
                            continue;
                        }

                        if (buildInfo.objectToVirtualAsset.ContainsKey(referencedObject))
                        {
                            continue;
                        }

                        if (buildInfo.assetLoadInfo.ContainsKey(referencedObject.guid))
                        {
                            continue;
                        }

                        assetBundleObjects.Add(new BuildCommandSet.SerializationInfo
                        {
                            serializationObject = referencedObject,
                            serializationIndex  = SerializationIndexFromObjectIdentifier(referencedObject)
                        });
                    }

                    BuildUsageTagGlobal globalUsage;
                    if (buildInfo.sceneUsageTags.TryGetValue(asset, out globalUsage))
                    {
                        command.sceneBundle  = true;
                        command.globalUsage |= globalUsage;
                    }
                }

                dependencies.Remove(bundle.Key);
                assetBundleObjects.Sort(Compare);

                command.assetBundleName         = bundle.Key;
                command.explicitAssets          = explicitAssets.ToArray();
                command.assetBundleDependencies = dependencies.OrderBy(x => x).ToArray();
                command.assetBundleObjects      = assetBundleObjects.ToArray();
                commands.Add(command);
            }

            output          = new BuildCommandSet();
            output.commands = commands.ToArray();

            if (UseCache && !BuildCache.SaveCachedResults(hash, output))
            {
                BuildLogger.LogWarning("Unable to cache CommandSetProcessor results.");
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }
コード例 #8
0
 private void SaveToCache(Hash128 hash, BuildInput output)
 {
     BuildCache.SaveCachedResults(hash, output);
 }
コード例 #9
0
        public override BuildPipelineCodes Convert(BuildDependencyInfo input, BuildSettings settings, bool aggressive, out BuildDependencyInfo output)
        {
            StartProgressBar("Generated shared object bundles", 3);

            Hash128 hash = CalculateInputHash(input);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out output))
            {
                EndProgressBar();
                return(BuildPipelineCodes.SuccessCached);
            }

            // Mutating the input
            output = input;

            if (!UpdateProgressBar("Generate lookup of all objects"))
            {
                EndProgressBar();
                return(BuildPipelineCodes.Canceled);
            }

            // Generate mapping of each object to the bundles it would be used by
            var objectToBundles = new Dictionary <ObjectIdentifier, HashSet <string> >();
            var objectToAssets  = new Dictionary <ObjectIdentifier, HashSet <GUID> >();

            foreach (var asset in input.assetInfo.Values)
            {
                var dependencies = input.assetToBundles[asset.asset];

                if (aggressive && !asset.includedObjects.IsNullOrEmpty())
                {
                    for (int i = 1; i < asset.includedObjects.Count; ++i)
                    {
                        var objectID = asset.includedObjects[i];

                        HashSet <string> bundles;
                        objectToBundles.GetOrAdd(objectID, out bundles);
                        bundles.Add(dependencies[0]);

                        HashSet <GUID> assets;
                        objectToAssets.GetOrAdd(objectID, out assets);
                        assets.Add(asset.asset);
                    }
                }

                foreach (var referenceID in asset.referencedObjects)
                {
                    if (!aggressive && input.assetToBundles.ContainsKey(referenceID.guid))
                    {
                        continue;
                    }

                    if (referenceID.filePath == BuildWriteProcessor.kUnityDefaultResourcePath)
                    {
                        continue;
                    }

                    HashSet <string> bundles;
                    objectToBundles.GetOrAdd(referenceID, out bundles);
                    bundles.Add(dependencies[0]);

                    HashSet <GUID> assets;
                    objectToAssets.GetOrAdd(referenceID, out assets);
                    assets.Add(asset.asset);
                }
            }


            if (!UpdateProgressBar("Finding set of reused objects"))
            {
                EndProgressBar();
                return(BuildPipelineCodes.Canceled);
            }

            // Generate the set of reused objects
            var hashToObjects = new Dictionary <Hash128, List <ObjectIdentifier> >();

            foreach (var objectPair in objectToBundles)
            {
                if (objectPair.Value.Count <= 1)
                {
                    continue;
                }

                var bundleHash = HashingMethods.CalculateMD5Hash(objectPair.Value.ToArray());

                List <ObjectIdentifier> objectIDs;
                hashToObjects.GetOrAdd(bundleHash, out objectIDs);
                objectIDs.Add(objectPair.Key);
            }


            if (!UpdateProgressBar("Creating shared object bundles"))
            {
                EndProgressBar();
                return(BuildPipelineCodes.Canceled);
            }

            // Generate Shared Bundles
            foreach (var hashPair in hashToObjects)
            {
                // Generate Dependency Information for virtual asset
                var assetInfo = new AssetLoadInfo();
                assetInfo.asset             = new GUID(hashPair.Key.ToString());
                assetInfo.address           = hashPair.Key.ToString();
                assetInfo.includedObjects   = hashPair.Value.ToList();
                assetInfo.referencedObjects = new List <ObjectIdentifier>();
                assetInfo.includedObjects.Sort((x, y) => { if (x < y)
                                                           {
                                                               return(-1);
                                                           }
                                                           if (x > y)
                                                           {
                                                               return(1);
                                                           }
                                                           return(0); });

                // Add new AssetLoadInfo for virtual asset
                output.assetInfo.Add(assetInfo.asset, assetInfo);
                var assetBundles = new List <string>();
                assetBundles.Add(assetInfo.address);

                // Add new bundle as dependency[0] for virtual asset
                output.assetToBundles.Add(assetInfo.asset, assetBundles);
                var bundleAssets = new List <GUID>();
                bundleAssets.Add(assetInfo.asset);

                // Add virtual asset to the list of assets for new bundle
                output.bundleToAssets.Add(assetInfo.address, bundleAssets);

                // Add virtual asset to lookup
                output.virtualAssets.Add(assetInfo.asset);

                foreach (var objectID in assetInfo.includedObjects)
                {
                    // Add objects in virtual asset to lookup
                    output.objectToVirtualAsset.Add(objectID, assetInfo.asset);
                    var assets = objectToAssets[objectID];
                    foreach (var asset in assets)
                    {
                        if (!output.assetToBundles.TryGetValue(asset, out assetBundles))
                        {
                            continue;
                        }

                        if (assetBundles.Contains(assetInfo.address))
                        {
                            continue;
                        }

                        // Add new bundle as dependency to assets referencing virtual asset objects
                        assetBundles.Add(assetInfo.address);
                    }
                }
            }

            // Generate Shared Bundle Build Dependencies
            foreach (var virtualAsset in output.virtualAssets)
            {
                var assetInfo    = output.assetInfo[virtualAsset];
                var dependencies = output.assetToBundles[virtualAsset];

                var references = BundleBuildInterface.GetPlayerDependenciesForObjects(assetInfo.includedObjects.ToArray(), settings.target, settings.typeDB);
                foreach (var reference in references)
                {
                    GUID          dependency;
                    List <string> bundles;

                    string depStr = "";

                    // If the reference is to an object in a virtual asset, no major checks, just add it as a dependency
                    if (output.objectToVirtualAsset.TryGetValue(reference, out dependency))
                    {
                        if (dependency == virtualAsset)
                        {
                            continue;
                        }

                        depStr = dependency.ToString();
                    }
                    // Otherwise if this reference is part of an asset assigned to a bundle, then set the bundle as a dependency to the virtual asset
                    else if (output.assetToBundles.TryGetValue(reference.guid, out bundles))
                    {
                        if (bundles.IsNullOrEmpty())
                        {
                            continue;
                        }

                        depStr = bundles[0];
                    }

                    if (dependencies.Contains(depStr))
                    {
                        continue;
                    }

                    dependencies.Add(depStr);
                }
            }

            if (UseCache && !BuildCache.SaveCachedResults(hash, output))
            {
                BuildLogger.LogWarning("Unable to cache SharedObjectProcessor results.");
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }
コード例 #10
0
        public override BuildPipelineCodes Convert(AssetInfoMap assetLoadInfo, out AssetInfoMap output)
        {
            StartProgressBar("Stripping unused sprite source textures", 3);

            if (!UpdateProgressBar("Finding sprite source textures"))
            {
                output = null;
                return(BuildPipelineCodes.Canceled);
            }
            var spriteRefCount = new Dictionary <ObjectIdentifier, int>();

            foreach (var assetInfo in assetLoadInfo)
            {
                var path     = AssetDatabase.GUIDToAssetPath(assetInfo.Value.asset.ToString());
                var importer = AssetImporter.GetAtPath(path) as TextureImporter;
                if (importer != null && importer.textureType == TextureImporterType.Sprite && !string.IsNullOrEmpty(importer.spritePackingTag))
                {
                    spriteRefCount[assetInfo.Value.includedObjects[0]] = 0;
                }
            }

            Hash128 hash = CalculateInputHash(assetLoadInfo, spriteRefCount);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out output))
            {
                EndProgressBar();
                return(BuildPipelineCodes.SuccessCached);
            }

            // Mutating the input, this is the only converter that does this
            output = assetLoadInfo;

            if (!UpdateProgressBar("Finding sprite source textures usage"))
            {
                EndProgressBar();
                return(BuildPipelineCodes.Canceled);
            }
            foreach (var assetInfo in output)
            {
                if (!string.IsNullOrEmpty(assetInfo.Value.processedScene))
                {
                    continue;
                }

                foreach (var reference in assetInfo.Value.referencedObjects)
                {
                    int refCount = 0;
                    if (!spriteRefCount.TryGetValue(reference, out refCount))
                    {
                        continue;
                    }

                    // Note: Because pass by value
                    spriteRefCount[reference] = ++refCount;
                }
            }

            if (!UpdateProgressBar("Removing unused sprite source textures."))
            {
                EndProgressBar();
                return(BuildPipelineCodes.Canceled);
            }
            foreach (var source in spriteRefCount)
            {
                if (source.Value > 0)
                {
                    continue;
                }

                var assetInfo       = output[source.Key.guid];
                var includedObjects = assetInfo.includedObjects;
                includedObjects.RemoveAt(0);
            }

            if (UseCache && !BuildCache.SaveCachedResults(hash, output))
            {
                BuildLogger.LogWarning("Unable to cache SpriteSourceProcessor results.");
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }