Ejemplo n.º 1
0
        internal void CalculateInputDefinitions(AddressableAssetSettings settings)
        {
            foreach (AddressableAssetGroup group in settings.groups)
            {
                if (group.HasSchema <BundledAssetGroupSchema>())
                {
                    var schema = group.GetSchema <BundledAssetGroupSchema>();
                    List <AssetBundleBuild> bundleInputDefinitions = new List <AssetBundleBuild>();
                    BuildScriptPackedMode.PrepGroupBundlePacking(group, bundleInputDefinitions, m_Locations,
                                                                 schema.BundleMode);

                    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);
                }
            }
        }
        internal static HashSet <string> GetGroupGuidsWithUnchangedBundleName(AddressableAssetSettings settings, Dictionary <AddressableAssetEntry, List <AddressableAssetEntry> > dependencyMap, AddressablesContentState cacheData)
        {
            var result = new HashSet <string>();

            if (cacheData == null)
            {
                return(result);
            }

            Dictionary <string, string> groupGuidToCacheBundleName = GetGroupGuidToCacheBundleNameMap(cacheData);

            foreach (AddressableAssetGroup group in settings.groups)
            {
                if (group == null || !group.HasSchema <BundledAssetGroupSchema>())
                {
                    continue;
                }

                var schema = group.GetSchema <BundledAssetGroupSchema>();
                List <AssetBundleBuild> bundleInputDefinitions = new List <AssetBundleBuild>();

                BuildScriptPackedMode.PrepGroupBundlePacking(group, bundleInputDefinitions, schema, x => !dependencyMap.ContainsKey(x));
                BuildScriptPackedMode.HandleDuplicateBundleNames(bundleInputDefinitions);

                for (int i = 0; i < bundleInputDefinitions.Count; i++)
                {
                    string bundleName = Path.GetFileNameWithoutExtension(bundleInputDefinitions[i].assetBundleName);
                    if (groupGuidToCacheBundleName.TryGetValue(group.Guid, out string cacheBundleName) && cacheBundleName == bundleName)
                    {
                        result.Add(group.Guid);
                    }
                }
            }
            return(result);
        }
 protected void Setup()
 {
     m_BuilderInput = new AddressablesDataBuilderInput(Settings);
     m_BuildScript  = ScriptableObject.CreateInstance <BuildScriptPackedMode>();
     m_BuildScript.InitializeBuildContext(m_BuilderInput, out m_BuildContext);
     m_RuntimeData = m_BuildContext.runtimeData;
 }
        public void PrepGroupBundlePacking_PackTogetherByLabel_GroupChangeDoesAffectBuildInput()
        {
            //Setup
            CreateGroupWithAssets("PrepGroup", 2, out AddressableAssetGroup group, out List <AddressableAssetEntry> entries);
            string label = "testlabel";

            entries[0].SetLabel(label, true, true, false);
            entries[1].SetLabel(label, true, true, false);
            var schema = ScriptableObject.CreateInstance <BundledAssetGroupSchema>();

            schema.BundleMode           = BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel;
            schema.InternalBundleIdMode = BundledAssetGroupSchema.BundleInternalIdMode.GroupGuidProjectIdEntriesHash;

            List <AssetBundleBuild> buildInputDefs = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs, schema);

            entries[1].SetLabel(label, false, true, false);

            List <AssetBundleBuild> buildInputDefs2 = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs2, schema);

            Assert.AreNotEqual(buildInputDefs[0].assetBundleName, buildInputDefs2[0].assetBundleName);
        }
        protected void PlayerDataSchemaTestsSetup()
        {
            m_BuilderInput = new AddressablesDataBuilderInput(m_Settings);
            m_BuildScript  = ScriptableObject.CreateInstance <BuildScriptPackedMode>();
            m_BuildScript.InitializeBuildContext(m_BuilderInput, out m_BuildContext);

            m_ScenesBkp = EditorBuildSettings.scenes;
            EditorBuildSettings.scenes = new EditorBuildSettingsScene[0];
        }
        public void ErrorCheckBundleSettings_FindsNoProblemsInDefaultScema()
        {
            var group  = Settings.CreateGroup("PackedTest", false, false, false, null, typeof(BundledAssetGroupSchema));
            var schema = group.GetSchema <BundledAssetGroupSchema>();

            var errorStr = BuildScriptPackedMode.ErrorCheckBundleSettings(schema, group, Settings);

            LogAssert.NoUnexpectedReceived();
            Assert.IsTrue(string.IsNullOrEmpty(errorStr));
        }
        public void WhenUsingLocalContentAndCompressionIsLZMA_ErrorCheckBundleSettings_LogsWarning()
        {
            var group  = Settings.CreateGroup("PackedTest", false, false, false, null, typeof(BundledAssetGroupSchema));
            var schema = group.GetSchema <BundledAssetGroupSchema>();

            schema.Compression = BundledAssetGroupSchema.BundleCompressionMode.LZMA;

            BuildScriptPackedMode.ErrorCheckBundleSettings(schema, group, Settings);
            LogAssert.Expect(LogType.Warning, $"Bundle compression is set to LZMA, but group {group.Name} uses local content.");
        }
 protected void TearDown()
 {
     m_BuilderInput = null;
     Object.DestroyImmediate(m_BuildScript);
     m_BuildScript = null;
     m_AssetBundle?.Unload(true);
     m_AssetBundle = null;
     Object.DestroyImmediate(m_PersistedSettings, true);
     m_PersistedSettings = null;
 }
        public void CalculateGroupHash_WithGroupGuidMode_GeneratesStableBundleNameWhenEntriesChange()
        {
            var group    = m_Settings.CreateGroup(nameof(CalculateGroupHash_WithGroupGuidMode_GeneratesStableBundleNameWhenEntriesChange), false, false, false, null, typeof(BundledAssetGroupSchema));
            var schema   = group.GetSchema <BundledAssetGroupSchema>();
            var expected = group.Guid;

            Assert.AreEqual(expected, BuildScriptPackedMode.CalculateGroupHash(BundledAssetGroupSchema.BundleInternalIdMode.GroupGuid, group, group.entries));
            group.AddAssetEntry(new AddressableAssetEntry("test", "test", group, true));
            Assert.AreEqual(expected, BuildScriptPackedMode.CalculateGroupHash(BundledAssetGroupSchema.BundleInternalIdMode.GroupGuid, group, group.entries));
            m_Settings.RemoveGroupInternal(group, true, false);
        }
        public void CalculateGroupHash_WithGroupGuidProjectIdEntryHashMode_GeneratesNewBundleNameWhenEntriesChange()
        {
            var group    = m_Settings.CreateGroup(nameof(CalculateGroupHash_WithGroupGuidProjectIdEntryHashMode_GeneratesNewBundleNameWhenEntriesChange), false, false, false, null, typeof(BundledAssetGroupSchema));
            var schema   = group.GetSchema <BundledAssetGroupSchema>();
            var expected = HashingMethods.Calculate(group.Guid, Application.cloudProjectId, new HashSet <string>(group.entries.Select(e => e.guid))).ToString();

            Assert.AreEqual(expected, BuildScriptPackedMode.CalculateGroupHash(BundledAssetGroupSchema.BundleInternalIdMode.GroupGuidProjectIdEntriesHash, group, group.entries));
            group.AddAssetEntry(new AddressableAssetEntry("test", "test", group, true));
            Assert.AreNotEqual(expected, BuildScriptPackedMode.CalculateGroupHash(BundledAssetGroupSchema.BundleInternalIdMode.GroupGuidProjectIdEntriesHash, group, group.entries));
            m_Settings.RemoveGroupInternal(group, true, false);
        }
        public void ErrorCheckBundleSettings_WarnsOfMismatchedLoadPath()
        {
            var group  = Settings.CreateGroup("PackedTest", false, false, false, null, typeof(BundledAssetGroupSchema));
            var schema = group.GetSchema <BundledAssetGroupSchema>();

            schema.LoadPath.Id = "BadPath";

            var errorStr = BuildScriptPackedMode.ErrorCheckBundleSettings(schema, group, Settings);

            LogAssert.NoUnexpectedReceived();
            Assert.IsTrue(errorStr.Contains("is set to the dynamic-lookup version of StreamingAssets, but LoadPath is not."));
        }
        public void SetAssetEntriesBundleFileIdToCatalogEntryBundleFileId_SetsBundleFileIdToBundleNameOnly_WhenGroupSchemaNamingIsSetToFilename()
        {
            //Setup
            GUID   entry1Guid         = GUID.Generate();
            string bundleFile         = "bundle";
            string internalBundleName = "bundlepath";
            string finalBundleName    = "finalBundlePath";
            string bundleCatalogEntryInternalIdHashed   = "catalogentrybundlefileid_1234567890.bundle";
            string bundleCatalogEntryInternalIdUnHashed = "catalogentrybundlefileid.bundle";

            AddressableAssetEntry entry1 = new AddressableAssetEntry(entry1Guid.ToString(), "123", null, false);
            AddressableAssetGroup group  = Settings.CreateGroup("testGroup", false, false, false,
                                                                new List <AddressableAssetGroupSchema>(), typeof(BundledAssetGroupSchema));

            group.GetSchema <BundledAssetGroupSchema>().BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.NoHash;
            group.AddAssetEntry(entry1, false);

            ICollection <AddressableAssetEntry> entries = new List <AddressableAssetEntry>()
            {
                entry1
            };

            Dictionary <string, string> bundleToIdMap = new Dictionary <string, string>()
            {
                { internalBundleName, finalBundleName }
            };

            IBundleWriteData writeData = new BundleWriteData();

            writeData.AssetToFiles.Add(entry1Guid, new List <string>()
            {
                bundleFile
            });
            writeData.FileToBundle.Add(bundleFile, internalBundleName);

            Dictionary <string, ContentCatalogDataEntry> catalogMap = new Dictionary <string, ContentCatalogDataEntry>()
            {
                {
                    finalBundleName,
                    new ContentCatalogDataEntry(typeof(IAssetBundleResource), bundleCatalogEntryInternalIdHashed,
                                                typeof(AssetBundleProvider).FullName, new[] { "catalogentry" })
                }
            };

            //Test
            BuildScriptPackedMode.SetAssetEntriesBundleFileIdToCatalogEntryBundleFileId(entries, bundleToIdMap, writeData, catalogMap);

            //Assert
            Assert.AreEqual(bundleCatalogEntryInternalIdUnHashed, entry1.BundleFileId);

            //Cleanup
            Settings.RemoveGroup(group);
        }
        public void HandleBundlesNaming_NamesShouldAlwaysBeUnique(List <AssetBundleBuild> bundleBuilds)
        {
            var group = Settings.CreateGroup("PackedTest", false, false, false, null, typeof(BundledAssetGroupSchema));
            var bundleToAssetGroup = new Dictionary <string, string>();

            List <string> uniqueNames = BuildScriptPackedMode.HandleDuplicateBundleNames(bundleBuilds, bundleToAssetGroup, group.Guid);

            var uniqueNamesInBundleBuilds = bundleBuilds.Select(b => b.assetBundleName).Distinct();

            Assert.AreEqual(bundleBuilds.Count, uniqueNames.Count());
            Assert.AreEqual(bundleBuilds.Count, uniqueNamesInBundleBuilds.Count());
            Assert.AreEqual(bundleBuilds.Count, bundleToAssetGroup.Count);
        }
Ejemplo n.º 14
0
        public void PrepGroupBundlePacking_WhenEntriesDontExpand_AllAssetEntriesAreReturned([Values] BundledAssetGroupSchema.BundlePackingMode mode)
        {
            int entryCount = 2;

            CreateGroupWithAssets("PrepGroup1", entryCount, out AddressableAssetGroup group, out List <AddressableAssetEntry> entries);
            for (int i = 0; i < entryCount; i++)
            {
                entries[i].SetLabel($"label", true, true, false);
            }
            List <AssetBundleBuild>      buildInputDefs = new List <AssetBundleBuild>();
            List <AddressableAssetEntry> retEntries     = BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs, mode);

            CollectionAssert.AreEquivalent(retEntries, entries);
        }
        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();
            }
        }
Ejemplo n.º 16
0
        public void PrepGroupBundlePacking_PackTogether_GroupChangeDoesAffectBuildInput()
        {
            CreateGroupWithAssets("PrepGroup", 2, out AddressableAssetGroup group, out List <AddressableAssetEntry> entries);

            List <AssetBundleBuild> buildInputDefs = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs, BundledAssetGroupSchema.BundlePackingMode.PackTogether);

            group.RemoveAssetEntry(entries[1]);

            List <AssetBundleBuild> buildInputDefs2 = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs2, BundledAssetGroupSchema.BundlePackingMode.PackTogether);

            Assert.AreNotEqual(buildInputDefs[0].assetBundleName, buildInputDefs2[0].assetBundleName);
        }
        public void PrepGroupBundlePacking_PackSeperate_GroupChangeDoesntAffectOtherAssetsBuildInput()
        {
            CreateGroupWithAssets("PrepGroup", 2, out AddressableAssetGroup group, out List <AddressableAssetEntry> entries);
            var schema = ScriptableObject.CreateInstance <BundledAssetGroupSchema>();

            schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately;
            List <AssetBundleBuild> buildInputDefs = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs, schema);

            group.RemoveAssetEntry(entries[1]);

            List <AssetBundleBuild> buildInputDefs2 = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs2, schema);

            Assert.AreEqual(buildInputDefs[0].assetBundleName, buildInputDefs2[0].assetBundleName);
        }
        protected void TearDown()
        {
            m_BuilderInput = null;
            Object.DestroyImmediate(m_BuildScript);
            m_BuildScript = null;
            m_AssetBundle?.Unload(true);
            m_AssetBundle = null;
            Object.DestroyImmediate(m_PersistedSettings, true);
            m_PersistedSettings        = null;
            EditorBuildSettings.scenes = m_ScenesBkp;
            AssetDatabase.Refresh();

            if (Directory.Exists(k_SchemaTestFolder))
            {
                Directory.Delete(k_SchemaTestFolder, true);
            }

            AssetDatabase.Refresh();
        }
        public void SetAssetEntriesBundleFileIdToCatalogEntryBundleFileId_ModifiedOnlyAssetEntries_ThatAreIncludedInBuildWriteData()
        {
            GUID   entry1Guid                   = GUID.Generate();
            GUID   entry2Guid                   = GUID.Generate();
            string bundleFile                   = "bundle";
            string internalBundleName           = "bundlepath";
            string finalBundleName              = "finalBundlePath";
            string bundleCatalogEntryInternalId = "catalogentrybundlefileid";

            AddressableAssetEntry entry1 = new AddressableAssetEntry(entry1Guid.ToString(), "123", null, false);
            AddressableAssetEntry entry2 = new AddressableAssetEntry(entry2Guid.ToString(), "456", null, false);
            ICollection <AddressableAssetEntry> entries = new List <AddressableAssetEntry>()
            {
                entry1, entry2
            };

            Dictionary <string, string> bundleToIdMap = new Dictionary <string, string>()
            {
                { internalBundleName, finalBundleName }
            };

            IBundleWriteData writeData = new BundleWriteData();

            writeData.AssetToFiles.Add(entry1Guid, new List <string>()
            {
                bundleFile
            });
            writeData.FileToBundle.Add(bundleFile, internalBundleName);

            Dictionary <string, ContentCatalogDataEntry> catalogMap = new Dictionary <string, ContentCatalogDataEntry>()
            {
                {
                    finalBundleName,
                    new ContentCatalogDataEntry(typeof(IAssetBundleResource), bundleCatalogEntryInternalId,
                                                typeof(AssetBundleProvider).FullName, new[] { "catalogentry" })
                }
            };

            BuildScriptPackedMode.SetAssetEntriesBundleFileIdToCatalogEntryBundleFileId(entries, bundleToIdMap, writeData, catalogMap);

            Assert.AreEqual(bundleCatalogEntryInternalId, entry1.BundleFileId);
            Assert.IsNull(entry2.BundleFileId);
        }
        public void GenerateBuildInputDefinition_WithInternalIdModes_GeneratesExpectedAddresses()
        {
            var group               = m_Settings.CreateGroup("DynamicInternalIdGroup", false, false, false, null, typeof(BundledAssetGroupSchema));
            var entries             = new List <AddressableAssetEntry>();
            AddressableAssetEntry e = new AddressableAssetEntry($"abcde", $"addr0", group, false);

            e.m_cachedAssetPath = "Assets/DummyPath0.asset";
            entries.Add(e);

            e = new AddressableAssetEntry($"abcdf", $"addr0", group, false);
            e.m_cachedAssetPath = "Assets/DummyPath0.asset";
            entries.Add(e);

            e = new AddressableAssetEntry($"abcdg", $"addr0", group, false);
            e.m_cachedAssetPath = "Assets/DummyPath0.asset";
            entries.Add(e);

            e = new AddressableAssetEntry($"axcde", $"addr0", group, false);
            e.m_cachedAssetPath = "Assets/DummyPath0.asset";
            entries.Add(e);

            var schema = group.GetSchema <BundledAssetGroupSchema>();

            schema.InternalIdNamingMode = BundledAssetGroupSchema.AssetNamingMode.FullPath;
            var bundleBuild = BuildScriptPackedMode.GenerateBuildInputDefinition(entries, "bundle");

            Assert.AreEqual("Assets/DummyPath0.asset", bundleBuild.addressableNames[0]);

            schema.InternalIdNamingMode = BundledAssetGroupSchema.AssetNamingMode.Filename;
            bundleBuild = BuildScriptPackedMode.GenerateBuildInputDefinition(entries, "bundle");
            Assert.AreEqual("DummyPath0.asset", bundleBuild.addressableNames[0]);

            schema.InternalIdNamingMode = BundledAssetGroupSchema.AssetNamingMode.GUID;
            bundleBuild = BuildScriptPackedMode.GenerateBuildInputDefinition(entries, "bundle");
            Assert.AreEqual("abcde", bundleBuild.addressableNames[0]);

            schema.InternalIdNamingMode = BundledAssetGroupSchema.AssetNamingMode.Dynamic;
            bundleBuild = BuildScriptPackedMode.GenerateBuildInputDefinition(entries, "bundle");
            Assert.AreEqual("a", bundleBuild.addressableNames[0]);
            Assert.AreEqual("ab", bundleBuild.addressableNames[1]);
            Assert.AreEqual("abc", bundleBuild.addressableNames[2]);
            Assert.AreEqual("ax", bundleBuild.addressableNames[3]);
        }
        public void PrepGroupBundlePacking_PackTogether_GroupChangeDoesAffectBuildInput()
        {
            CreateGroupWithAssets("PrepGroup", 2, out AddressableAssetGroup group, out List <AddressableAssetEntry> entries);
            var schema = ScriptableObject.CreateInstance <BundledAssetGroupSchema>();

            schema.BundleMode           = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
            schema.InternalBundleIdMode = BundledAssetGroupSchema.BundleInternalIdMode.GroupGuidProjectIdEntriesHash;

            List <AssetBundleBuild> buildInputDefs = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs, schema);

            group.RemoveAssetEntry(entries[1]);

            List <AssetBundleBuild> buildInputDefs2 = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs2, schema);

            Assert.AreNotEqual(buildInputDefs[0].assetBundleName, buildInputDefs2[0].assetBundleName);
        }
Ejemplo n.º 22
0
        public void PrepGroupBundlePacking_PackTogetherByLabel_GroupChangeDoesAffectBuildInput()
        {
            //Setup
            CreateGroupWithAssets("PrepGroup", 2, out AddressableAssetGroup group, out List <AddressableAssetEntry> entries);
            string label = "testlabel";

            entries[0].SetLabel(label, true, true, false);
            entries[1].SetLabel(label, true, true, false);

            List <AssetBundleBuild> buildInputDefs = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs, BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel);

            entries[1].SetLabel(label, false, true, false);

            List <AssetBundleBuild> buildInputDefs2 = new List <AssetBundleBuild>();

            BuildScriptPackedMode.PrepGroupBundlePacking(group, buildInputDefs2, BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel);

            Assert.AreNotEqual(buildInputDefs[0].assetBundleName, buildInputDefs2[0].assetBundleName);
        }
        List <AnalyzeResult> DoFakeBuild(AddressableAssetSettings settings)
        {
            m_ImplicitAssets = new HashSet <GUID>();
            List <AnalyzeResult> emptyResult = new List <AnalyzeResult>();

            emptyResult.Add(new AnalyzeResult(ruleName + " - No issues found"));
            var context = new AddressablesDataBuilderInput(settings);
            var timer   = new Stopwatch();

            timer.Start();
            var aaSettings = context.AddressableSettings;

            //gather entries
            var locations          = new List <ContentCatalogDataEntry>();
            var allBundleInputDefs = new List <AssetBundleBuild>();
            var bundleToAssetGroup = new Dictionary <string, string>();
            var runtimeData        = new ResourceManagerRuntimeData();

            runtimeData.LogResourceManagerExceptions = aaSettings.buildSettings.LogResourceManagerExceptions;

            foreach (var assetGroup in aaSettings.groups)
            {
                var schema = assetGroup.GetSchema <BundledAssetGroupSchema>();
                if (schema == null)
                {
                    continue;
                }

                var bundleInputDefs = new List <AssetBundleBuild>();
                BuildScriptPackedMode.PrepGroupBundlePacking(assetGroup, bundleInputDefs, locations, schema.BundleMode);
                for (int i = 0; i < bundleInputDefs.Count; i++)
                {
                    if (bundleToAssetGroup.ContainsKey(bundleInputDefs[i].assetBundleName))
                    {
                        var bid     = bundleInputDefs[i];
                        int count   = 1;
                        var newName = bid.assetBundleName;
                        while (bundleToAssetGroup.ContainsKey(newName) && count < 1000)
                        {
                            newName = bid.assetBundleName.Replace(".bundle", string.Format("{0}.bundle", count++));
                        }
                        bundleInputDefs[i] = new AssetBundleBuild {
                            assetBundleName = newName, addressableNames = bid.addressableNames, assetBundleVariant = bid.assetBundleVariant, assetNames = bid.assetNames
                        };
                    }

                    bundleToAssetGroup.Add(bundleInputDefs[i].assetBundleName, assetGroup.Guid);
                }
                allBundleInputDefs.AddRange(bundleInputDefs);
            }
            ExtractDataTask extractData = new ExtractDataTask();

            if (allBundleInputDefs.Count > 0)
            {
                if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
                {
                    Debug.LogError("Cannot run Analyze with unsaved scenes");
                    return(emptyResult);
                }

                var buildTarget             = context.Target;
                var buildTargetGroup        = context.TargetGroup;
                var buildParams             = new AddressableAssetsBundleBuildParameters(aaSettings, bundleToAssetGroup, buildTarget, buildTargetGroup, aaSettings.buildSettings.bundleBuildPath);
                var builtinShaderBundleName = aaSettings.DefaultGroup.Name.ToLower().Replace(" ", "").Replace('\\', '/').Replace("//", "/") + "_unitybuiltinshaders.bundle";
                var buildTasks = RuntimeDataBuildTasks(builtinShaderBundleName);
                buildTasks.Add(extractData);

                var aaContext = new AddressableAssetsBuildContext
                {
                    settings           = aaSettings,
                    runtimeData        = runtimeData,
                    bundleToAssetGroup = bundleToAssetGroup,
                    locations          = locations
                };

                IBundleBuildResults buildResults;
                var exitCode = ContentPipeline.BuildAssetBundles(buildParams, new BundleBuildContent(allBundleInputDefs), out buildResults, buildTasks, aaContext);
                GenerateLocationListsTask.Run(aaContext, extractData.WriteData);
                if (exitCode < ReturnCode.Success)
                {
                    Debug.LogError("Analyze build failed. " + exitCode);
                    return(emptyResult);
                }

                HashSet <GUID> explicitGuids = new HashSet <GUID>();
                foreach (var atf in extractData.WriteData.AssetToFiles)
                {
                    explicitGuids.Add(atf.Key);
                }

                Dictionary <GUID, List <string> > implicitGuids = new Dictionary <GUID, List <string> >();
                foreach (var fto in extractData.WriteData.FileToObjects)
                {
                    foreach (ObjectIdentifier g in fto.Value)
                    {
                        if (!explicitGuids.Contains(g.guid))
                        {
                            if (!implicitGuids.ContainsKey(g.guid))
                            {
                                implicitGuids.Add(g.guid, new List <string>());
                            }
                            implicitGuids[g.guid].Add(fto.Key);
                        }
                    }
                }

                //dictionary<group, dictionary<bundle, implicit assets >>
                Dictionary <string, Dictionary <string, List <string> > > allIssues = new Dictionary <string, Dictionary <string, List <string> > >();
                foreach (var g in implicitGuids)
                {
                    if (g.Value.Count > 1) //it's duplicated...
                    {
                        var path = AssetDatabase.GUIDToAssetPath(g.Key.ToString());
                        if (!AddressableAssetUtility.IsPathValidForEntry(path) ||
                            path.ToLower().Contains("/resources/") ||
                            path.ToLower().StartsWith("resources/"))
                        {
                            continue;
                        }

                        foreach (var file in g.Value)
                        {
                            var    bun = extractData.WriteData.FileToBundle[file];
                            string groupGuid;
                            if (aaContext.bundleToAssetGroup.TryGetValue(bun, out groupGuid))
                            {
                                var group = aaSettings.FindGroup(grp => grp.Guid == groupGuid);
                                if (group != null)
                                {
                                    Dictionary <string, List <string> > groupData;
                                    if (!allIssues.TryGetValue(group.Name, out groupData))
                                    {
                                        groupData = new Dictionary <string, List <string> >();
                                        allIssues.Add(group.Name, groupData);
                                    }

                                    List <string> assets;
                                    if (!groupData.TryGetValue(bun, out assets))
                                    {
                                        assets = new List <string>();
                                        groupData.Add(bun, assets);
                                    }
                                    assets.Add(path);

                                    m_ImplicitAssets.Add(g.Key);
                                }
                            }
                        }
                    }
                }

                List <AnalyzeResult> result = new List <AnalyzeResult>();
                foreach (var group in allIssues)
                {
                    foreach (var bundle in group.Value)
                    {
                        foreach (var item in bundle.Value)
                        {
                            var issueName = ruleName + kDelimiter + group.Key + kDelimiter + bundle.Key + kDelimiter + item;
                            result.Add(new AnalyzeResult(issueName, MessageType.Warning));
                        }
                    }
                }

                if (result.Count > 0)
                {
                    return(result);
                }
            }
            return(emptyResult);
        }