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));
    }
Example #3
0
 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);
 }
Example #4
0
        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;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #5
0
    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);
    }
Example #10
0
        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;
                        }
                    }
                }
            }
        }