internal static List <AssetEntryRevertOperation> DetermineRequiredAssetEntryUpdates(AddressableAssetGroup group, ContentUpdateScript.ContentUpdateContext contentUpdateContext) { if (!group.HasSchema <BundledAssetGroupSchema>()) { return(new List <AssetEntryRevertOperation>()); } bool groupIsStaticContentGroup = group.HasSchema <ContentUpdateGroupSchema>() && group.GetSchema <ContentUpdateGroupSchema>().StaticContent; List <AssetEntryRevertOperation> operations = new List <AssetEntryRevertOperation>(); foreach (AddressableAssetEntry entry in group.entries) { GUID guid = new GUID(entry.guid); if (!contentUpdateContext.WriteData.AssetToFiles.ContainsKey(guid)) { continue; } string file = contentUpdateContext.WriteData.AssetToFiles[guid][0]; string fullInternalBundleName = contentUpdateContext.WriteData.FileToBundle[file]; string finalBundleWritePath = contentUpdateContext.BundleToInternalBundleIdMap[fullInternalBundleName]; //Ensure we can get the catalog entry for the bundle we're looking to replace if (!contentUpdateContext.IdToCatalogDataEntryMap.TryGetValue(finalBundleWritePath, out ContentCatalogDataEntry catalogBundleEntry)) { continue; } //If new entries are added post initial build this will ensure that those new entries have their bundleFileId for SaveContentState entry.BundleFileId = catalogBundleEntry.InternalId; //If we have no cached state no reason to proceed. This is new to the build. if (!contentUpdateContext.GuidToPreviousAssetStateMap.TryGetValue(entry.guid, out CachedAssetState previousAssetState)) { continue; } //If the parent group is different we don't want to revert it to its previous state if (entry.parentGroup.Guid != previousAssetState.groupGuid) { continue; } //If the asset hash has changed and the group is not a static content update group we don't want to revert it to its previous state if (AssetDatabase.GetAssetDependencyHash(entry.AssetPath) != previousAssetState.asset.hash && !groupIsStaticContentGroup) { continue; } //If the previous asset state has the same bundle file id as the current build we don't want to revert it to its previous state if (catalogBundleEntry.InternalId == previousAssetState.bundleFileId) { continue; } var schema = group.GetSchema <BundledAssetGroupSchema>(); string loadPath = schema.LoadPath.GetValue(group.Settings); string buildPath = schema.BuildPath.GetValue(group.Settings); //Need to check and make sure our cached version exists if (string.IsNullOrEmpty(previousAssetState.bundleFileId)) { //Logging this as an error because a CachedAssetState without a set bundleFileId is indicative of a significant issue with the build script. Addressables.LogError($"CachedAssetState found for {entry.AssetPath} but the bundleFileId was never set on the previous build."); continue; } string previousBundlePath = previousAssetState.bundleFileId?.Replace(loadPath, buildPath); if (!File.Exists(previousBundlePath)) { //Logging this as a warning because users may choose to delete their bundles on disk which will trigger this state. Addressables.LogWarning($"CachedAssetState found for {entry.AssetPath} but the previous bundle at {previousBundlePath} cannot be found. " + $"The modified assets will not be able to use the previously built bundle which will result in new bundles being created " + $"for these static content groups. This will point the Content Catalog to local bundles that do not exist on currently " + $"deployed versions of an application."); continue; } string builtBundlePath = contentUpdateContext.BundleToInternalBundleIdMap[fullInternalBundleName].Replace(loadPath, buildPath); AssetEntryRevertOperation operation = new AssetEntryRevertOperation() { BundleCatalogEntry = catalogBundleEntry, AssetEntry = entry, CurrentBuildPath = builtBundlePath, PreviousAssetState = previousAssetState, PreviousBuildPath = previousBundlePath }; operations.Add(operation); } return(operations); }
private ContentUpdateScript.ContentUpdateContext GetContentUpdateContext(string contentUpdateTestAssetGUID, string contentUpdateTestCachedAssetHash, string contentUpdateTestNewInternalBundleName, string contentUpdateTestNewBundleName, string contentUpdateTestCachedBundlePath, string contentUpdateTestGroupGuid, string contentUpdateTestFileName) { Dictionary <string, string> bundleToInternalBundle = new Dictionary <string, string>() { { contentUpdateTestNewInternalBundleName, contentUpdateTestNewBundleName } }; Dictionary <string, CachedAssetState> guidToCachedState = new Dictionary <string, CachedAssetState>() { //entry 1 { contentUpdateTestAssetGUID, new CachedAssetState() { bundleFileId = contentUpdateTestCachedBundlePath, asset = new AssetState() { guid = new GUID(contentUpdateTestAssetGUID), hash = Hash128.Parse(contentUpdateTestCachedAssetHash) }, dependencies = new AssetState[] { }, data = null, groupGuid = contentUpdateTestGroupGuid } } }; Dictionary <string, ContentCatalogDataEntry> idToCatalogEntryMap = new Dictionary <string, ContentCatalogDataEntry>() { //bundle entry { contentUpdateTestNewBundleName, new ContentCatalogDataEntry(typeof(IAssetBundleResource), contentUpdateTestNewBundleName, typeof(AssetBundleProvider).FullName, new [] { contentUpdateTestNewBundleName }) }, //asset entry { contentUpdateTestAssetGUID, new ContentCatalogDataEntry(typeof(IResourceLocation), contentUpdateTestAssetGUID, typeof(BundledAssetProvider).FullName, new [] { contentUpdateTestAssetGUID }) } }; IBundleWriteData writeData = new BundleWriteData(); writeData.AssetToFiles.Add(new GUID(contentUpdateTestAssetGUID), new List <string>() { contentUpdateTestFileName }); writeData.FileToBundle.Add(contentUpdateTestFileName, contentUpdateTestNewInternalBundleName); ContentUpdateScript.ContentUpdateContext context = new ContentUpdateScript.ContentUpdateContext() { WriteData = writeData, BundleToInternalBundleIdMap = bundleToInternalBundle, GuidToPreviousAssetStateMap = guidToCachedState, IdToCatalogDataEntryMap = idToCatalogEntryMap, ContentState = new AddressablesContentState(), PreviousAssetStateCarryOver = new List <CachedAssetState>(), Registry = new FileRegistry() }; return(context); }