/// <summary> /// Creates a new asset bundle patch. /// </summary> /// <param name="previousBundlePatches">List of previously created bundle patches.</param> /// <param name="currentBundle">Up-to-date bundle with all assets.</param> /// <param name="currentBundlePatch">Output bundle patch.</param> /// <param name="baseBundleVersion">Version on the last bundle patch in the previousBundlePatches list.</param> public static void CreatePatch( List <AssetBundle> previousBundlePatches, AssetBundle currentBundle, AssetBundle currentBundlePatch, int baseBundleVersion) { // Build up list of files inherited from the base bundle. var inheritedFiles = new HashSet <string>(); foreach (var patch in previousBundlePatches) { foreach (var file in patch.EnumerateFiles()) { inheritedFiles.Add(file); } var manifest = PackedAssetBundle.Manifest.Create(patch); foreach (var deletedFile in manifest.DeletedAssets) { inheritedFiles.Remove(deletedFile); } } // Import new or modified files. var previousPatchesReversed = previousBundlePatches.ToList(); previousPatchesReversed.Reverse(); foreach (var file in currentBundle.EnumerateFiles()) { if (!inheritedFiles.Contains(file)) { // Import a new file. ImportAsset(file, currentBundle, currentBundlePatch); continue; } var fileModified = true; foreach (var patch in previousPatchesReversed) { if (!patch.FileExists(file)) { continue; } // Don't compare last write time because it can be different for the same files on different machines. if ( currentBundle.GetAttributes(file) == patch.GetAttributes(file) && currentBundle.GetSourceExtension(file) == patch.GetSourceExtension(file) && AreByteArraysEqual(currentBundle.GetCookingRulesSHA1(file), patch.GetCookingRulesSHA1(file)) && AreFilesEqual(file, patch, currentBundle) ) { fileModified = false; } break; } if (fileModified) { ImportAsset(file, currentBundle, currentBundlePatch); } } // Prepare the current bundle manifest. var currentManifest = new PackedAssetBundle.Manifest(); // Build up deleted files list. foreach (var file in inheritedFiles) { if (inheritedFiles.Contains(file) && !currentBundle.FileExists(file) && file != PackedAssetBundle.Manifest.FileName) { currentManifest.DeletedAssets.Add(file); } } currentManifest.BaseBundleVersion = baseBundleVersion; currentManifest.Write(currentBundlePatch); }