bool HasRequiredSchemas(AddressableAssetSettings settings, AddressableAssetGroup group) { bool hasBundledSchema = group.HasSchema <BundledAssetGroupSchema>(); bool hasPADSchema = group.HasSchema <PlayAssetDeliverySchema>(); if (!hasBundledSchema && !hasPADSchema) { return(false); } if (!hasBundledSchema && hasPADSchema) { Addressables.LogWarning($"Group '{group.name}' has a '{typeof(PlayAssetDeliverySchema).Name}' but not a '{typeof(BundledAssetGroupSchema).Name}'. " + $"It does not contain any bundled content to be assigned to an asset pack."); return(false); } if (hasBundledSchema && !hasPADSchema) { var bundledSchema = group.GetSchema <BundledAssetGroupSchema>(); string buildPath = bundledSchema.BuildPath.GetValue(settings); if (BuildPathIncludedInStreamingAssets(buildPath)) { Addressables.Log($"Group '{group.name}' does not have a '{typeof(PlayAssetDeliverySchema).Name}' but its build path '{buildPath}' will be included in StreamingAssets at build time. " + $"The group will be assigned to the generated asset packs unless its build path is changed."); } return(false); } return(true); }
protected override string ProcessGroup(AddressableAssetGroup assetGroup, AddressableAssetsBuildContext aaContext) { if (assetGroup.HasSchema <TextureVariationSchema>()) { ProcessTextureScaler(assetGroup.GetSchema <TextureVariationSchema>(), assetGroup, aaContext); } if (assetGroup.HasSchema <PrefabTextureVariantSchema>()) { ProcessVariants(assetGroup.GetSchema <PrefabTextureVariantSchema>(), assetGroup, aaContext); } return(base.ProcessGroup(assetGroup, aaContext)); }
internal static bool GroupFilter(AddressableAssetGroup g) { if (g == null) { return(false); } if (!g.HasSchema <ContentUpdateGroupSchema>() || !g.GetSchema <ContentUpdateGroupSchema>().StaticContent) { return(false); } if (!g.HasSchema <BundledAssetGroupSchema>() || !g.GetSchema <BundledAssetGroupSchema>().IncludeInBuild) { return(false); } return(true); }
private void PostProcessCatalogEnteries(AddressableAssetGroup group, IBundleWriteData writeData, List <ContentCatalogDataEntry> locations, FileRegistry fileRegistry) { if (!group.HasSchema <BundledAssetGroupSchema>() || !File.Exists(ContentUpdateScript.GetContentStateDataPath(false))) { return; } AddressablesContentState contentState = ContentUpdateScript.LoadContentState(ContentUpdateScript.GetContentStateDataPath(false)); foreach (AddressableAssetEntry entry in group.entries) { CachedAssetState cachedAsset = contentState.cachedInfos.FirstOrDefault(i => i.asset.guid.ToString() == entry.guid); if (cachedAsset != null) { if (entry.parentGroup.Guid == cachedAsset.groupGuid) { GUID guid = new GUID(entry.guid); if (!writeData.AssetToFiles.ContainsKey(guid)) { continue; } string file = writeData.AssetToFiles[guid][0]; string fullBundleName = writeData.FileToBundle[file]; ContentCatalogDataEntry catalogBundleEntry = locations.FirstOrDefault((loc) => (loc.Keys[0] as string) == fullBundleName); if (catalogBundleEntry != null) { if (String.IsNullOrEmpty(entry.BundleFileId)) { entry.BundleFileId = catalogBundleEntry.InternalId; } else { if (catalogBundleEntry.InternalId != cachedAsset.bundleFileId) { string unusedBundlePath = fileRegistry.GetFilePathForBundle( Path.GetFileNameWithoutExtension(fullBundleName)); if (File.Exists(unusedBundlePath) && fileRegistry.ReplaceBundleEntry( Path.GetFileNameWithoutExtension(fullBundleName), cachedAsset.bundleFileId)) { File.Delete(unusedBundlePath); catalogBundleEntry.InternalId = entry.BundleFileId; catalogBundleEntry.Data = cachedAsset.data; } } } } } } } }
protected override string ProcessGroup(AddressableAssetGroup assetGroup, AddressableAssetsBuildContext aaContext) { if (assetGroup.HasSchema <TextureVariationSchema>()) { var errorString = ProcessTextureScaler(assetGroup.GetSchema <TextureVariationSchema>(), assetGroup, aaContext); if (!string.IsNullOrEmpty(errorString)) { return(errorString); } } return(base.ProcessGroup(assetGroup, aaContext)); }
protected override string ProcessGroup(AddressableAssetGroup assetGroup, AddressableAssetsBuildContext aaContext) { if (assetGroup.HasSchema <ProcessVariantAssetsSchema>()) { ProcessVariantAssetsSchema schema = assetGroup.GetSchema <ProcessVariantAssetsSchema>(); var errorString = ProcessVariants(schema, assetGroup, aaContext); if (!string.IsNullOrEmpty(errorString)) { return(errorString); } } return(base.ProcessGroup(assetGroup, aaContext)); }
internal void CalculateInputDefinitions(AddressableAssetSettings settings) { int updateFrequency = Mathf.Max(settings.groups.Count / 10, 1); bool progressDisplayed = false; for (int groupIndex = 0; groupIndex < settings.groups.Count; ++groupIndex) { AddressableAssetGroup group = settings.groups[groupIndex]; if (group == null) { continue; } if (!progressDisplayed || groupIndex % updateFrequency == 0) { progressDisplayed = true; if (EditorUtility.DisplayCancelableProgressBar("Calculating Input Definitions", "", (float)groupIndex / settings.groups.Count)) { m_AssetEntries.Clear(); m_BundleToAssetGroup.Clear(); m_AllBundleInputDefs.Clear(); break; } } if (group.HasSchema <BundledAssetGroupSchema>()) { var schema = group.GetSchema <BundledAssetGroupSchema>(); List <AssetBundleBuild> bundleInputDefinitions = new List <AssetBundleBuild>(); m_AssetEntries.AddRange(BuildScriptPackedMode.PrepGroupBundlePacking(group, bundleInputDefinitions, schema)); for (int i = 0; i < bundleInputDefinitions.Count; i++) { if (m_BundleToAssetGroup.ContainsKey(bundleInputDefinitions[i].assetBundleName)) { bundleInputDefinitions[i] = CreateUniqueBundle(bundleInputDefinitions[i]); } m_BundleToAssetGroup.Add(bundleInputDefinitions[i].assetBundleName, schema.Group.Guid); } m_AllBundleInputDefs.AddRange(bundleInputDefinitions); } } if (progressDisplayed) { EditorUtility.ClearProgressBar(); } }
public void DupeGroupHasContentUpdateSchema() { //Setup var group1 = Settings.CreateGroup("CheckDupeDepencency1", false, false, false, null, typeof(BundledAssetGroupSchema)); var group2 = Settings.CreateGroup("CheckDupeDepencency2", false, false, false, null, typeof(BundledAssetGroupSchema)); Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(k_CheckDupePrefabA), group1, false, false); Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(k_CheckDupePrefabB), group2, false, false); var rule = new CheckBundleDupeDependencies(); //Test rule.FixIssues(Settings); AddressableAssetGroup group = Settings.FindGroup("Duplicate Asset Isolation"); //Assert Assert.IsNotNull(group); Assert.IsTrue(group.HasSchema <ContentUpdateGroupSchema>()); Assert.IsTrue(group.GetSchema <ContentUpdateGroupSchema>().StaticContent); //Cleanup Settings.RemoveGroup(group); }
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 void PostProcessCatalogEnteries(AddressableAssetGroup group, IBundleWriteData writeData, List <ContentCatalogDataEntry> locations, FileRegistry fileRegistry) { if (!group.HasSchema <BundledAssetGroupSchema>() || !File.Exists(ContentUpdateScript.GetContentStateDataPath(false))) { return; } AddressablesContentState contentState = ContentUpdateScript.LoadContentState(ContentUpdateScript.GetContentStateDataPath(false)); foreach (AddressableAssetEntry entry in group.entries) { CachedAssetState cachedAsset = contentState.cachedInfos.FirstOrDefault(i => i.asset.guid.ToString() == entry.guid); if (cachedAsset != null) { GUID guid = new GUID(entry.guid); if (!writeData.AssetToFiles.ContainsKey(guid)) { continue; } string file = writeData.AssetToFiles[guid][0]; string fullBundleName = writeData.FileToBundle[file]; string convertedLocation = m_BundleToInternalId[fullBundleName]; ContentCatalogDataEntry catalogBundleEntry = locations.FirstOrDefault((loc) => loc.InternalId == (convertedLocation)); if (catalogBundleEntry != null) { if (entry.parentGroup.Guid == cachedAsset.groupGuid) { //Asset hash hasn't changed if (AssetDatabase.GetAssetDependencyHash(entry.AssetPath) == cachedAsset.asset.hash) { if (catalogBundleEntry.InternalId != cachedAsset.bundleFileId) { string builtBundlePath = m_BundleToInternalId[fullBundleName].Replace( group.GetSchema <BundledAssetGroupSchema>().LoadPath.GetValue(group.Settings), group.GetSchema <BundledAssetGroupSchema>().BuildPath.GetValue(group.Settings)); string cachedBundlePath = cachedAsset.bundleFileId?.Replace( group.GetSchema <BundledAssetGroupSchema>().LoadPath.GetValue(group.Settings), group.GetSchema <BundledAssetGroupSchema>().BuildPath.GetValue(group.Settings)); //Need to check and make sure our cached version exists if (!string.IsNullOrEmpty(cachedBundlePath) && File.Exists(cachedBundlePath)) { //Try and replace the new bundle entry with the cached one and delete the new bundle if (File.Exists(builtBundlePath) && fileRegistry.ReplaceBundleEntry( Path.GetFileNameWithoutExtension(convertedLocation), cachedAsset.bundleFileId)) { File.Delete(builtBundlePath); catalogBundleEntry.InternalId = cachedAsset.bundleFileId; catalogBundleEntry.Data = cachedAsset.data; entry.BundleFileId = cachedAsset.bundleFileId; } } } } entry.BundleFileId = catalogBundleEntry.InternalId; cachedAsset.bundleFileId = catalogBundleEntry.InternalId; } } } } }