private void CacheDataForCommandSet(BuildCommandSet commandSet) { if (!UseCache) { return; } m_NameToDependencies.Clear(); m_AssetToHash.Clear(); // Generate data needed for cache hash generation foreach (var command in commandSet.commands) { var dependencies = new List <string>(); m_NameToDependencies[command.assetBundleName] = dependencies; dependencies.Add(command.assetBundleName); foreach (var dependency in command.assetBundleDependencies) { dependencies.Add(dependency); } foreach (var objectID in command.assetBundleObjects) { if (m_AssetToHash.ContainsKey(objectID.serializationObject.guid)) { continue; } var path = AssetDatabase.GUIDToAssetPath(objectID.serializationObject.guid.ToString()); m_AssetToHash[objectID.serializationObject.guid] = AssetDatabase.GetAssetDependencyHash(path).ToString(); } } }
private static void DebugPrintCommandSet(ref BuildCommandSet commandSet) { // TODO: this debug printing function is ugly as sin, fix it var msg = new StringBuilder(); if (!commandSet.commands.IsNullOrEmpty()) { foreach (var bundle in commandSet.commands) { msg.AppendFormat("Bundle: '{0}'\n", bundle.assetBundleName); if (!bundle.explicitAssets.IsNullOrEmpty()) { msg.Append("\tExplicit Assets:\n"); foreach (var asset in bundle.explicitAssets) { // TODO: Create GUIDToAssetPath that takes GUID struct var addressableName = string.IsNullOrEmpty(asset.address) ? AssetDatabase.GUIDToAssetPath(asset.asset.ToString()) : asset.address; msg.AppendFormat("\t\tAsset: {0} - '{1}'\n", asset.asset, addressableName); if (!asset.includedObjects.IsNullOrEmpty()) { msg.Append("\t\t\tIncluded Objects:\n"); foreach (var obj in asset.includedObjects) { msg.AppendFormat("\t\t\t\t{0}\n", obj); } } if (!asset.referencedObjects.IsNullOrEmpty()) { msg.Append("\t\t\tReferenced Objects:\n"); foreach (var obj in asset.referencedObjects) { msg.AppendFormat("\t\t\t\t{0}\n", obj); } } } } if (!bundle.assetBundleObjects.IsNullOrEmpty()) { msg.Append("\tAsset Bundle Objects:\n"); foreach (var obj in bundle.assetBundleObjects) { msg.AppendFormat("\t\t{0}: {1}\n", obj.serializationIndex, obj.serializationObject); } } if (!bundle.assetBundleDependencies.IsNullOrEmpty()) { msg.Append("\tAsset Bundle Dependencies:\n"); foreach (var dependency in bundle.assetBundleDependencies) { msg.AppendFormat("\t\t{0}\n", dependency); } } msg.Append("\n"); } } BuildLogger.Log(msg); }
private static void DebugPrintCommandSet(ref BuildCommandSet commandSet) { var msg = ""; if (commandSet.commands != null) { foreach (var bundle in commandSet.commands) { msg += string.Format("{0}\n", bundle.assetBundleName); if (bundle.explicitAssets != null) { foreach (var asset in bundle.explicitAssets) { msg += string.Format("\t{0}\n", asset.asset); if (asset.includedObjects != null) { foreach (var obj in asset.includedObjects) { msg += string.Format("\t\t{0}\n", obj); } } msg += "\t\t------------------------------\n"; if (asset.referencedObjects != null) { foreach (var obj in asset.referencedObjects) { msg += string.Format("\t\t{0}\n", obj); } } } } if (bundle.assetBundleObjects != null) { foreach (var obj in bundle.assetBundleObjects) { msg += string.Format("\t{0}\n", obj); } } if (bundle.assetBundleDependencies != null) { foreach (var dependency in bundle.assetBundleDependencies) { msg += string.Format("\t{0}\n", dependency); } } } } UnityEngine.Debug.Log(msg); }
public static void CalculateAssetBundleBuildDependencies(ref BuildCommandSet commandSet) { // Dictionary for quick included asset lookup var assetToBundleMap = new Dictionary <GUID, string>(); for (var i = 0; i < commandSet.commands.Length; ++i) { var bundle = commandSet.commands[i]; foreach (var asset in bundle.explicitAssets) { assetToBundleMap.Add(asset.asset, commandSet.commands[i].assetBundleName); } } // Calculate dependencies for each bundle for (var i = 0; i < commandSet.commands.Length; ++i) { CalculateAssetBundleDependencies(ref commandSet.commands[i], assetToBundleMap); } }
static void CreateContentCatalog(BuildCommandSet commandSet) { const string kLocalAssetBundle = "localassetbundle"; const string kBundledAsset = "bundledasset"; var locations = new List <ResourceManagerImpl.ResourceLocation>(); foreach (var cmd in commandSet.commands) { locations.Add(new ResourceManagerImpl.ResourceLocation(cmd.assetBundleName, Path.Combine(relativeStreamingAssetsBundlePath, cmd.assetBundleName), kLocalAssetBundle, cmd.assetBundleDependencies)); if (!string.IsNullOrEmpty(cmd.scene)) { var id = Path.GetFileNameWithoutExtension(cmd.scene); var name = string.Concat("Scene::", id); locations.Add(new ResourceManagerImpl.ResourceLocation(name, id, kLocalAssetBundle, new string[] { cmd.assetBundleName })); } else if (cmd.explicitAssets.Length > 0) { foreach (var info in cmd.explicitAssets) { locations.Add(new ResourceManagerImpl.ResourceLocation(info.address, info.address, kBundledAsset, new string[] { cmd.assetBundleName })); } } } var cc = ScriptableObject.CreateInstance <ContentCatalog>(); cc.locations = locations; cc.locations.Sort(); if (File.Exists(kContentCatalogPath)) { File.Delete(kContentCatalogPath); } Directory.CreateDirectory(Path.GetDirectoryName(kContentCatalogPath)); AssetDatabase.CreateAsset(cc, kContentCatalogPath); }
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); }
public static BuildPipelineCodes Build(BuildDependencyInformation buildInfo, out BuildCommandSet commandSet, bool useCache = false, BuildProgressTracker progressTracker = null) { commandSet = new BuildCommandSet(); // Strip out sprite source textures if nothing references them directly var spriteSourceProcessor = new SpriteSourceProcessor(useCache, progressTracker); var exitCode = spriteSourceProcessor.Convert(buildInfo.assetLoadInfo, out buildInfo.assetLoadInfo); if (exitCode < BuildPipelineCodes.Success) { return(exitCode); } // Generate the commandSet from the calculated dependency information var commandSetProcessor = new CommandSetProcessor(useCache, progressTracker); exitCode = commandSetProcessor.Convert(buildInfo, out commandSet); if (exitCode < BuildPipelineCodes.Success) { return(exitCode); } return(exitCode); }
public static BuildPipelineCodes Build(BuildSettings settings, BuildCompression compression, string outputFolder, BuildDependencyInformation buildInfo, BuildCommandSet commandSet, out BundleBuildResult result, bool useCache = false, BuildProgressTracker progressTracker = null) { result = new BundleBuildResult(); // Write out resource files var commandSetWriter = new CommandSetWriter(useCache, progressTracker); var exitCode = commandSetWriter.Convert(commandSet, settings, out result.bundleDetails); if (exitCode < BuildPipelineCodes.Success) { return(exitCode); } // Archive and compress resource files var resourceArchiver = new ResourceFileArchiver(useCache, progressTracker); exitCode = resourceArchiver.Convert(result.bundleDetails, buildInfo.sceneResourceFiles, compression, outputFolder, out result.bundleCRCs); if (exitCode < BuildPipelineCodes.Success) { return(exitCode); } // Generate Unity5 compatible manifest files //string[] manifestfiles; //var manifestWriter = new Unity5ManifestWriter(useCache, true); //if (!manifestWriter.Convert(commandSet, output, crc, outputFolder, out manifestfiles)) // return false; return(exitCode); }
public static BuildCommandSet GenerateBuildCommandSet(BuildInput input, BuildSettings settings) { // Rebuild sprite atlas cache for correct dependency calculation Packer.RebuildAtlasCacheIfNeeded(settings.target, true, Packer.Execution.Normal); // Need to specal case sprites as we only want to include the source texutre in certain situations m_SpriteMap.Clear(); // Create commands array matching the size of the input var commandSet = new BuildCommandSet(); commandSet.commands = new BuildCommandSet.Command[input.definitions.Length]; for (var i = 0; i < input.definitions.Length; ++i) { var definition = input.definitions[i]; // Populate each command from asset bundle definition var command = new BuildCommandSet.Command(); command.assetBundleName = definition.assetBundleName; command.explicitAssets = new BuildCommandSet.AssetLoadInfo[definition.explicitAssets.Length]; // Fill out asset load info and references for each asset in the definition var allObjects = new HashSet <ObjectIdentifier>(); for (var j = 0; j < definition.explicitAssets.Length; ++j) { var explicitAsset = new BuildCommandSet.AssetLoadInfo(); explicitAsset.asset = definition.explicitAssets[j]; explicitAsset.path = AssetDatabase.GUIDToAssetPath(explicitAsset.asset.ToString()); explicitAsset.includedObjects = AssetBundleBuildInterface.GetObjectIdentifiersInAsset(definition.explicitAssets[j]); explicitAsset.referencedObjects = AssetBundleBuildInterface.GetPlayerDependenciesForObjects(explicitAsset.includedObjects); // Is this asset a sprite? var type = AssetDatabase.GetMainAssetTypeAtPath(explicitAsset.path); if (type == typeof(Texture2D) && explicitAsset.referencedObjects.Length == 1) { // Source texture should always be the first included object, atlas should always be the first referenced object m_SpriteMap[explicitAsset.referencedObjects[0].guid] = new StriteTextures(explicitAsset.includedObjects[0], explicitAsset.referencedObjects[0], command.assetBundleName); } command.explicitAssets[j] = explicitAsset; allObjects.UnionWith(explicitAsset.includedObjects); allObjects.UnionWith(explicitAsset.referencedObjects); } command.assetBundleObjects = allObjects.ToArray(); commandSet.commands[i] = command; } // TODO: Debug printing DebugPrintCommandSet(ref commandSet); // At this point, We have generated fully self contained asset bundles with 0 dependencies. // Default implementation is to reduce duplication of objects by declaring dependencies to other asset // bundles if that other asset bundle has an explicit asset declared that contains the objects needed // We also remove any built in unity objects as they are built with the player (We may want to change this part in the future) CalculateAssetBundleBuildDependencies(ref commandSet); // Note: I may, or may not feel dirty doing mutable things to what otherwise should be immutable struct // TODO: Debug printing DebugPrintCommandSet(ref commandSet); return(commandSet); }