static void OnPostHeaderGUI(Editor editor)
        {
            var aaSettings = AddressableAssetSettingsDefaultObject.Settings;
            var guid       = string.Empty;
            AddressableAssetEntry entry = null;

            if (editor.targets.Length > 0)
            {
                int  addressableCount = 0;
                bool foundValidAsset  = false;
                bool foundAssetGroup  = false;
                foreach (var t in editor.targets)
                {
                    string path;
                    Type   mainAssetType;
                    if (AddressableAssetUtility.GetPathAndGUIDFromTarget(t, out path, ref guid, out mainAssetType) &&
                        path.ToLower().Contains("assets") &&
                        mainAssetType != null)
                    {
                        // Is addressable group
                        if (path.ToLower().Contains("addressableassetsdata/assetgroups"))
                        {
                            foundAssetGroup = true;
                        }
                        // Is asset
                        if (!BuildUtility.IsEditorAssembly(mainAssetType.Assembly))
                        {
                            foundValidAsset = true;

                            if (aaSettings != null)
                            {
                                entry = aaSettings.FindAssetEntry(guid);
                                if (entry != null && !entry.IsSubAsset)
                                {
                                    addressableCount++;
                                }
                            }
                        }
                    }
                }

                if (foundAssetGroup)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Profile: " + AddressableAssetSettingsDefaultObject.GetSettings(true).profileSettings.
                                    GetProfileName(AddressableAssetSettingsDefaultObject.GetSettings(true).activeProfileId));

                    GUILayout.FlexibleSpace();
                    if (GUILayout.Button("System Settings", "MiniButton"))
                    {
                        EditorGUIUtility.PingObject(AddressableAssetSettingsDefaultObject.Settings);
                        Selection.activeObject = AddressableAssetSettingsDefaultObject.Settings;
                    }
                    GUILayout.EndHorizontal();
                }

                if (!foundValidAsset)
                {
                    return;
                }

                if (addressableCount == 0)
                {
                    if (GUILayout.Toggle(false, s_AddressableAssetToggleText, GUILayout.ExpandWidth(false)))
                    {
                        SetAaEntry(AddressableAssetSettingsDefaultObject.GetSettings(true), editor.targets, true);
                    }
                }
                else if (addressableCount == editor.targets.Length)
                {
                    GUILayout.BeginHorizontal();
                    if (!GUILayout.Toggle(true, s_AddressableAssetToggleText, GUILayout.ExpandWidth(false)))
                    {
                        SetAaEntry(aaSettings, editor.targets, false);
                    }

                    if (editor.targets.Length == 1 && entry != null)
                    {
                        entry.address = EditorGUILayout.DelayedTextField(entry.address, GUILayout.ExpandWidth(true));
                    }
                    GUILayout.EndHorizontal();
                }
                else
                {
                    GUILayout.BeginHorizontal();
                    if (s_ToggleMixed == null)
                    {
                        s_ToggleMixed = new GUIStyle("ToggleMixed");
                    }
                    if (GUILayout.Toggle(false, s_AddressableAssetToggleText, s_ToggleMixed, GUILayout.ExpandWidth(false)))
                    {
                        SetAaEntry(AddressableAssetSettingsDefaultObject.GetSettings(true), editor.targets, true);
                    }
                    EditorGUILayout.LabelField(addressableCount + " out of " + editor.targets.Length + " assets are addressable.");
                    GUILayout.EndHorizontal();
                }
            }
        }
        private void CreateAddressableSettings(bool localMode)
        {
            AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.GetSettings(true);

            settings.ActivePlayModeDataBuilderIndex = localMode ? 0 : 2;
            settings.BuildRemoteCatalog             = true;
            settings.DisableCatalogUpdateOnStartup  = true;

            // don't include built-in data, causes shader issues
            settings.groups.ForEach(g =>
            {
                PlayerDataGroupSchema schema = g.GetSchema <PlayerDataGroupSchema>();
                if (schema != null)
                {
                    schema.IncludeBuildSettingsScenes = false;
                    schema.IncludeResourcesFolders    = false;
                }
            });

            // setup profiles
            AddressableAssetProfileSettings profile = settings.profileSettings;

            // activate and (re)group assets
            foreach (string dir in GetLevelPaths())
            {
                string levelName = Path.GetFileName(dir);
                bool   isBase    = levelName == "Base";

                // create one profile per level
                string profileId = profile.GetProfileId(levelName);
                if (string.IsNullOrEmpty(profileId))
                {
                    profileId = profile.AddProfile(levelName, settings.activeProfileId);
                }

                string guid = AssetDatabase.AssetPathToGUID($"Assets/Levels/{levelName}");

                // create group if non-existent
                AddressableAssetGroup group = settings.groups.Where(g => g.name == levelName).FirstOrDefault();
                if (group == null)
                {
                    group = CreateAssetGroup <BundledAssetGroupSchema>(settings, levelName);
                }

                // set correct path
                AddressableAssetEntry entry = settings.CreateOrMoveEntry(guid, group);
                entry.SetAddress($"Levels/{levelName}");

                // set variables
                string localRoot = Application.dataPath + $"/../Library/com.unity.addressables/aa/Windows/Levels/{levelName}/[BuildTarget]";
                profile.SetValue(profileId, AddressableAssetSettings.kLocalBuildPath, localRoot);
                profile.SetValue(profileId, AddressableAssetSettings.kLocalLoadPath, localRoot);
                profile.SetValue(profileId, AddressableAssetSettings.kRemoteBuildPath, $"ServerData/Levels/{levelName}/[BuildTarget]");
                profile.SetValue(profileId, AddressableAssetSettings.kRemoteLoadPath, $"{AWSUtil.S3Root}Levels/{levelName}/[BuildTarget]");

                // ensure correct group settings
                BundledAssetGroupSchema groupSchema = group.GetSchema <BundledAssetGroupSchema>();
                groupSchema.UseAssetBundleCache = true;
                groupSchema.UseAssetBundleCrc   = false;
                groupSchema.IncludeInBuild      = isBase ? true : false;
                groupSchema.BundleNaming        = BundledAssetGroupSchema.BundleNamingStyle.NoHash; // hash to disimbiguate identically named files yields same error messages, e.g. standard shaders
                groupSchema.BundleMode          = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
                groupSchema.Compression         = BundledAssetGroupSchema.BundleCompressionMode.LZ4;
                groupSchema.BuildPath.SetVariableByName(settings, localMode ? AddressableAssetSettings.kLocalBuildPath : AddressableAssetSettings.kRemoteBuildPath);
                groupSchema.LoadPath.SetVariableByName(settings, localMode ? AddressableAssetSettings.kLocalLoadPath : AddressableAssetSettings.kRemoteLoadPath);
            }
        }
        public override void Build(BuildTarget target,
                                   Model.NodeData node,
                                   IEnumerable <PerformGraph.AssetGroups> incoming,
                                   IEnumerable <Model.ConnectionData> connectionsToOutput,
                                   PerformGraph.Output Output,
                                   Action <Model.NodeData, string, float> progressFunc)
        {
            var aaSettings = AddressableAssetSettingsDefaultObject.GetSettings(false);

            var registeredLabels = new List <string>();

            if (incoming != null)
            {
                foreach (var ag in incoming)
                {
                    foreach (var groupName in ag.assetGroups.Keys)
                    {
                        var labels = m_label.Replace("*", groupName).Split(',').Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)).Distinct();
                        if (labels.Any() || m_overwriteLabels)
                        {
                            var assets = ag.assetGroups [groupName];

                            foreach (var a in assets)
                            {
                                var entry = aaSettings.FindAssetEntry(a.assetDatabaseId);
                                if (entry == null)
                                {
                                    continue;
                                }

                                if (m_overwriteLabels)
                                {
                                    var removingLabelEnum = entry.labels.Except(labels);
                                    if (removingLabelEnum.Any())
                                    {
                                        var removingLabels = removingLabelEnum.ToList();
                                        foreach (var removingLabel in removingLabels)
                                        {
                                            entry.SetLabel(removingLabel, false);
                                        }
                                    }
                                }

                                var addingLabelEnum = labels.Except(entry.labels);
                                if (addingLabelEnum.Any())
                                {
                                    var addingLabels = addingLabelEnum.ToList();
                                    foreach (var addingLabel in addingLabels)
                                    {
                                        if (!registeredLabels.Contains(addingLabel))
                                        {
                                            aaSettings.AddLabel(addingLabel);
                                            registeredLabels.Add(addingLabel);
                                        }
                                        entry.SetLabel(addingLabel, true);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (Output != null)
            {
                var dst = (connectionsToOutput == null || !connectionsToOutput.Any())?
                          null : connectionsToOutput.First();

                if (incoming != null)
                {
                    foreach (var ag in incoming)
                    {
                        Output(dst, ag.assetGroups);
                    }
                }
                else
                {
                    Output(dst, new Dictionary <string, List <AssetReference> >());
                }
            }
        }
        private IEnumerator PackageLevels(bool allLevels, bool allTargets)
        {
            uploadPossible      = false;
            packagingInProgress = true;
            packagingSuccessful = false;

            try
            {
                string[] levelsToBuild = allLevels ? GetLevelPaths() : GetLevelsToBuild();
                if (levelsToBuild.Length == 0)
                {
                    yield break;
                }

                CreateLockFile();
                ConvertTileMaps();
                CreateAddressableSettings(!allTargets);
                EditorUserBuildSettings.androidBuildSubtarget    = MobileTextureSubtarget.Generic; // FIXME: ASTC resulting in pink shaders as of 2019.4+
                EditorUserBuildSettings.selectedStandaloneTarget = BuildTarget.StandaloneWindows64;
                AddressableAssetSettings.CleanPlayerContent();
                if (Directory.Exists(GetServerDataPath()) && (packageMode == 0 || allLevels))
                {
                    Directory.Delete(GetServerDataPath(), true);
                }

                // set build targets
                List <BuildTarget> targets = new List <BuildTarget>();
                if (!debugMode)
                {
                    targets.Add(BuildTarget.Android);
                }
                targets.Add(BuildTarget.StandaloneWindows64); // set windows last so that we can continue with editor iterations normally right afterwards

                // build each level individually
                AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.GetSettings(true);
                foreach (string dir in levelsToBuild)
                {
                    string levelName = Path.GetFileName(dir);

                    string serverDir = GetServerDataPath() + "/Levels/" + Path.GetFileName(dir);
                    if (packageMode == 1 && !allLevels && Directory.Exists(serverDir))
                    {
                        Directory.Delete(serverDir, true);
                    }

                    settings.activeProfileId = settings.profileSettings.GetProfileId(levelName);
                    settings.groups.ForEach(group =>
                    {
                        if (group.ReadOnly)
                        {
                            return;
                        }
                        group.GetSchema <BundledAssetGroupSchema>().IncludeInBuild = group.name == levelName;
                    });

                    BundledAssetGroupSchema schema = settings.groups.Where(group => group.name == levelName).First().GetSchema <BundledAssetGroupSchema>();
                    settings.RemoteCatalogBuildPath = schema.BuildPath;
                    settings.RemoteCatalogLoadPath  = schema.LoadPath;

                    if (allTargets)
                    {
                        // iterate over all supported platforms
                        foreach (BuildTarget target in targets)
                        {
                            EditorUserBuildSettings.SwitchActiveBuildTarget(target);
                            AddressableAssetSettings.BuildPlayerContent();
                        }
                    }
                    else
                    {
                        // build only for currently active target
                        AddressableAssetSettings.BuildPlayerContent();
                    }
                }
                CreateAddressableSettings(!allTargets); // do again to have clean build state, as some settings were messed with while building
                RenameCatalogs();
                packagingSuccessful = true;
            }
            catch (Exception e)
            {
                packagingInProgress = false;
                EditorUtility.DisplayDialog("Error", "Packaging could not be completed. Error: " + e.Message, "Close");
                yield break;
            }

            dirWatcher.ClearAffected(); // only do at end, since during build might cause false positives
            RemoveLockFile();
            packagingInProgress = false;

            Debug.Log("Packaging completed successfully.");
        }
        public static void AddFileToAddressables()
        {
            AddressablesRules rules = new AddressablesRules();
            Dictionary <string, BuildAddressablesData> bundles = rules.GetBuilds();
            AddressableAssetSettings aaSettings = AddressableAssetSettingsDefaultObject.GetSettings(false);
            AddressableAssetGroup    group      = null;

            //清理重名group
            foreach (string key in bundles.Keys)
            {
                group = aaSettings.groups.Find(x => x.Name == bundles[key].GroupName);
                if (group != null)
                {
                    aaSettings.RemoveGroup(group);
                    group = null;
                }
            }

            foreach (string key in bundles.Keys)
            {
                group = aaSettings.groups.Find(x => x.Name == bundles[key].GroupName);
                if (group == null)
                {
                    if (bundles[key].ResType == "online")
                    {
                        group = aaSettings.CreateGroup(bundles[key].GroupName, false, false, false, null);
                        BundledAssetGroupSchema schema = group.AddSchema <BundledAssetGroupSchema>();
                        schema.Compression = BundledAssetGroupSchema.BundleCompressionMode.LZ4;
                        if (bundles[key].packageType == "PackSeparately")
                        {
                            schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately;
                        }
                        else if (bundles[key].packageType == "PackTogether")
                        {
                            schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
                        }
                        else if (bundles[key].packageType == "PackTogetherByLabel")
                        {
                            schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel;
                        }
                        schema.BuildPath.SetVariableByName(group.Settings, AddressableAssetSettings.kRemoteBuildPath);
                        schema.LoadPath.SetVariableByName(group.Settings, AddressableAssetSettings.kRemoteLoadPath);
                        schema.UseAssetBundleCache = true;
                        schema.UseAssetBundleCrc   = true;
                        ContentUpdateGroupSchema contentUpdateGroupSchema = group.AddSchema <ContentUpdateGroupSchema>();
                        contentUpdateGroupSchema.StaticContent = false;
                        group = null;
                    }
                    else
                    {
                        group = aaSettings.CreateGroup(bundles[key].GroupName, false, false, false, null);
                        BundledAssetGroupSchema schema = group.AddSchema <BundledAssetGroupSchema>();
                        schema.Compression = BundledAssetGroupSchema.BundleCompressionMode.Uncompressed;
                        if (bundles[key].packageType == "PackSeparately")
                        {
                            schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately;
                        }
                        else if (bundles[key].packageType == "PackTogether")
                        {
                            schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
                        }
                        else if (bundles[key].packageType == "PackTogetherByLabel")
                        {
                            schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel;
                        }

                        if (bundles[key].canUpdate)
                        {
                            ContentUpdateGroupSchema contentUpdateGroupSchema = group.AddSchema <ContentUpdateGroupSchema>();
                            contentUpdateGroupSchema.StaticContent = false;
                        }

                        schema.UseAssetBundleCache = true;
                        schema.UseAssetBundleCrc   = true;
                        group = null;
                    }
                }
            }


            foreach (string key in bundles.Keys)
            {
                int count    = 0;
                int MaxCount = bundles[key].entitys.Count;
                group = aaSettings.groups.Find(x => x.Name == bundles[key].GroupName);
                foreach (string entitysKey in bundles[key].entitys.Keys)
                {
                    count++;
                    if (count % 3 == 0)
                    {
                        if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(
                                string.Format("Collecting... [{0}/{1}]", count, MaxCount), entitysKey,
                                count * 1f / MaxCount))
                        {
                            break;
                        }
                    }

                    string guid = AssetDatabase.AssetPathToGUID(bundles[key].entitys[entitysKey]);
                    AddressableAssetEntry entity = aaSettings.CreateOrMoveEntry(guid, group);
                    entity.SetAddress(entitysKey);
                    for (int i = 0; i < bundles[key].Lable.Length; i++)
                    {
                        aaSettings.AddLabel(bundles[key].Lable[i]);
                        entity.SetLabel(bundles[key].Lable[i], true);
                    }
                }
            }

            UnityEditor.EditorUtility.ClearProgressBar();
        }