using System; using System.IO; using System.Linq; using UnityEditor; using UnityEditor.AddressableAssets; using UnityEditor.AddressableAssets.Settings; using UnityEngine; using inspector.ext; using UnityEditor.AddressableAssets.Settings.GroupSchemas; using System.Collections.Generic; using UnityEngine.AddressableAssets; using System.Text.RegularExpressions; namespace addressables.helper { [Serializable] public class GroupDefine { public string name; [inspector.ext.Folder] public string folder; public string folderPath => folder.ToFolderInfo().path; public AddressableAssetGroupTemplate template; public AssetLabelReference[] labels; public void CopyToStreamingAssets() { var addrSettings = AddressableAssetSettingsDefaultObject.Settings; var group = addrSettings.FindGroup(name); var buildPath = group.Settings.RemoteCatalogBuildPath; var schema = group.GetSchema(); if (schema != null) { if (schema.BundleMode == BundledAssetGroupSchema.BundlePackingMode.PackSeparately) { foreach (var entry in group.entries) { if (entry.labels.Any(x => x == "pack")) { if (Directory.Exists(buildPath.GetValue(addrSettings)) == false) { Debug.LogError($"{group.name} {entry.address} {buildPath.GetValue(addrSettings)}"); continue; } string bundleName = Path.GetFileName(entry.BundleFileId); if (string.IsNullOrEmpty(bundleName)) { Debug.LogError($"{group.name} {entry.address}"); continue; } var bunldes = Directory.GetFiles(buildPath.GetValue(addrSettings), bundleName); if (bunldes.Length != 1) { Debug.LogError($"{group.name} {entry.address} {bunldes.Length} {bundleName}"); continue; } //copy bundle var dest = Path.Combine(Application.streamingAssetsPath, Path.GetFileName(bunldes[0])); File.Copy(bunldes[0], dest, true); } } } else if (schema.BundleMode == BundledAssetGroupSchema.BundlePackingMode.PackTogether) { foreach (var entry in group.entries) { if (entry.labels.Any(x => x == "pack")) { if (Directory.Exists(buildPath.GetValue(addrSettings)) == false) { Debug.LogError($"{group.name} {entry.address} {buildPath.GetValue(addrSettings)}"); continue; } string bundleName = Path.GetFileName(entry.BundleFileId); if (string.IsNullOrEmpty(bundleName)) { Debug.LogError($"{group.name} {entry.address}"); continue; } var bunldes = Directory.GetFiles(buildPath.GetValue(addrSettings), bundleName); if (bunldes.Length != 1) { Debug.LogError($"{group.name} {entry.address} {bunldes.Length} {bundleName}"); continue; } //copy bundle var dest = Path.Combine(Application.streamingAssetsPath, Path.GetFileName(bunldes[0])); File.Copy(bunldes[0], dest, true); return; } } } else if (schema.BundleMode == BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel) { List names = new List(); foreach (var entry in group.entries) { if (entry.labels.Any(x => x == "pack")) { if (Directory.Exists(buildPath.GetValue(addrSettings)) == false) { Debug.LogError($"{group.name} {entry.address} {buildPath.GetValue(addrSettings)}"); continue; } string bundleName = Path.GetFileName(entry.BundleFileId); if (string.IsNullOrEmpty(bundleName)) { Debug.LogError($"{group.name} {entry.address}"); continue; } if (names.Contains(bundleName)) { continue; } var bunldes = Directory.GetFiles(buildPath.GetValue(addrSettings), bundleName); if (bunldes.Length != 1) { Debug.LogError($"{group.name} {entry.address} {bunldes.Length} {bundleName}"); continue; } names.Add(bundleName); //copy bundle var dest = Path.Combine(Application.streamingAssetsPath, Path.GetFileName(bunldes[0])); File.Copy(bunldes[0], dest, true); } } } } } } [Serializable] public class GroupFolderDefine { public string name; [inspector.ext.Folder] public string folder; public string folderPath => folder.ToFolderInfo().path; public AddressableAssetGroupTemplate template; public AssetLabelReference[] labels; } public class AddressableHelperSetting : ScriptableObject { public string[] MamualGroupNames; public string[] MamualGroupNamePrefixs; public GroupDefine[] GroupDefines; public GroupFolderDefine[] GroupFolderDefines; } public class AddressableHelper { private const string helperSettingPath = "Assets/Settings/AddressableHelperSetting.asset"; public static bool IsSettingExists() => File.Exists(helperSettingPath); [MenuItem("Window/Asset Management/Helper/Create Setting", true)] static bool ValidateCreateSetting() => !IsSettingExists(); [MenuItem("Window/Asset Management/Helper/Create Setting")] static void CreateSetting() { var instance = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(instance, helperSettingPath); } //[MenuItem("Window/Asset Management/Helper/Sync Groups", true)] //static bool ValidateSyncGroups() => IsSettingExists(); //[MenuItem("Window/Asset Management/Helper/Sync Groups &#F")] public static void SyncGroups() { var helperSetting = AssetDatabase.LoadAssetAtPath(helperSettingPath); var defines = helperSetting.GroupDefines; var addrSettings = AddressableAssetSettingsDefaultObject.Settings; var manualGroupNames = helperSetting.MamualGroupNames; var MamualGroupNamePrefixs = helperSetting.MamualGroupNamePrefixs; // Debug.Log($"[AddressableHelper] {addrSettings.groups.Select(x => x.Name)}"); var dbt = addrSettings.groups; foreach (var x in dbt) { Debug.Log(x); } // Debug.Log($"[AddressableHelper] {addrSettings.groups.Select(x => x.Name).ToList()}"); var existsGroupNames = addrSettings.groups.Select(x => x.Name).ToList(); var newGroupNames = helperSetting.GroupDefines.Select(x => x.name) .Concat(helperSetting.GroupFolderDefines.Select(x => x.name)) .ToList(); var allGroupNames = manualGroupNames.Concat(newGroupNames).ToList(); for(int i = 0; i < MamualGroupNamePrefixs.Length;i++) { var prefix = MamualGroupNamePrefixs[i]; if (string.IsNullOrEmpty(prefix)) continue; var manualGroups = existsGroupNames.Where(x => x.StartsWith(prefix)).ToList(); if (manualGroups.Count > 0) { Debug.Log($"[AddressableHelper] add manual group {prefix}"); allGroupNames.AddRange(manualGroups); } } // remove groups not defined in helper setting for (int i = existsGroupNames.Count - 1; i >= 0; i--) { var group = existsGroupNames[i]; if (!allGroupNames.Contains(group)) { Debug.Log($"[AddressableHelper] remove group {group}"); addrSettings.RemoveGroup(addrSettings.FindGroup(group)); existsGroupNames.RemoveAt(i); } } foreach (var groupDefine in defines) { var groupName = groupDefine.name; var group = addrSettings.FindGroup(groupName); if (null == group) { Debug.Log($"[AddressableHelper] create group {groupDefine.name}"); group = CreateGroup(groupDefine, addrSettings); groupDefine.template.ApplyToAddressableAssetGroup(group); } else { var entries = group.entries.ToList(); Debug.Log($"[AddressableHelper] clean group {groupDefine.name} {entries.Count}"); foreach (var entry in entries) { group.RemoveAssetEntry(entry); } } Debug.Log($"[AddressableHelper] sync group {groupDefine.name}"); SyncEntries(groupDefine, group, addrSettings); EditorUtility.SetDirty(group); } var folderDefines = helperSetting.GroupFolderDefines; foreach (var folderDefine in folderDefines) { var groupName = folderDefine.name; var group = addrSettings.FindGroup(groupName); if (null == group) { Debug.Log($"[AddressableHelper] create group {folderDefine.name}"); group = CreateGroupByFolder(groupName, folderDefine, addrSettings); folderDefine.template.ApplyToAddressableAssetGroup(group); } else { var entries = group.entries.ToList(); Debug.Log($"[AddressableHelper] clean group {folderDefine.name} {entries.Count}"); foreach (var entry in entries) { group.RemoveAssetEntry(entry); } } Debug.Log($"[AddressableHelper] sync group {folderDefine.name}"); SyncEntriesByFolder(folderDefine, group, addrSettings); EditorUtility.SetDirty(group); } EditorUtility.SetDirty(addrSettings); AssetDatabase.SaveAssets(); } private static AddressableAssetGroup CreateGroupByFolder(string groupName, GroupFolderDefine groupDefine, AddressableAssetSettings addrSettings) { var template = groupDefine.template; var group = addrSettings.CreateGroup(groupName, false, false, true, null, template.GetTypes()); return group; } private static void SyncEntriesByFolder(GroupFolderDefine groupDefine, AddressableAssetGroup group, AddressableAssetSettings addrSettings) { var folder = new string[] { groupDefine.folderPath }; //获取文件夹下的所有文件夹 var assetsGUIDs = AssetDatabase.FindAssets("", folder); var assetPaths = assetsGUIDs.Select(_ => AssetDatabase.GUIDToAssetPath(_)).ToArray(); var count = assetsGUIDs.Length; Regex regexA = new Regex(groupDefine.folderPath + "/(.*?)/"); Regex regexB = new Regex(".*?/([^/]+)$"); for (int i = 0; i < count; i++) { var guid = assetsGUIDs[i]; var entry = group.GetAssetEntry(guid); string address = Path.GetFileNameWithoutExtension(assetPaths[i]); string folderName = Path.GetFileName(assetPaths[i]); if (folderName.Contains(".")) { if (entry == null || entry.address != address) { entry = addrSettings.CreateOrMoveEntry(guid, group); entry.address = address; //获取文件所在一级目录 string directoryPath = assetPaths[i]; //int startIndex = 1 + directoryPath.IndexOf(groupDefine.folderPath) + groupDefine.folderPath.Length; //int endIndex = directoryPath.IndexOf("/", startIndex); //directoryPath = directoryPath.Substring(startIndex, endIndex - startIndex); //directoryPath = assetPaths[i]; Match match = regexA.Match(directoryPath); if (match.Groups.Count > 1) { directoryPath = match.Groups[1].Value; } else { match = regexB.Match(groupDefine.folderPath); directoryPath = match.Groups[1].Value; } entry.SetLabel(directoryPath, true, true); for (int j = 0; j < groupDefine.labels.Length; j++) { if (!string.IsNullOrEmpty(groupDefine.labels[j].labelString)) { entry.SetLabel(groupDefine.labels[j].labelString, true); } } EditorUtility.SetDirty(group); } } } } private static void SyncEntries(GroupDefine groupDefine, AddressableAssetGroup group, AddressableAssetSettings addrSettings) { var folder = new string[] { groupDefine.folderPath }; var assetsGUIDs = AssetDatabase.FindAssets("", folder); var assetPaths = assetsGUIDs.Select(_ => AssetDatabase.GUIDToAssetPath(_)).ToArray(); var count = assetsGUIDs.Length; for (int i = 0; i < count; i++) { if (Directory.Exists(assetPaths[i])) continue; var guid = assetsGUIDs[i]; var entry = group.GetAssetEntry(guid); string address = Path.GetFileNameWithoutExtension(assetPaths[i]); if (entry == null || entry.address != address) { entry = addrSettings.CreateOrMoveEntry(guid, group); entry.address = address; for (int j = 0; j < groupDefine.labels.Length; j++) { if (!string.IsNullOrEmpty(groupDefine.labels[j].labelString)) { entry.SetLabel(groupDefine.labels[j].labelString, true); } } EditorUtility.SetDirty(group); } } } private static AddressableAssetGroup CreateGroup(GroupDefine groupDefine, AddressableAssetSettings addrSettings) { var template = groupDefine.template; var group = addrSettings.CreateGroup(groupDefine.name, false, false, true, null, template.GetTypes()); return group; } [MenuItem("Window/Asset Management/Helper/Clean StreamingAssets")] public static void CleanStreamingAssets() { // delete all file with ext .bundle in StreamingAssets fold string streamingAssetsPath = Application.streamingAssetsPath; string[] bundleFiles = Directory.GetFiles(streamingAssetsPath, "*.bundle"); string[] bundleMetaFiles = Directory.GetFiles(streamingAssetsPath, "*.bundle.meta"); foreach (string bundleFile in bundleFiles) { File.Delete(bundleFile); } foreach (string metaFile in bundleMetaFiles) { File.Delete(metaFile); } AssetDatabase.Refresh(); } [MenuItem("Window/Asset Management/Helper/Copy To StreamingAssets")] public static void CopyToStreamingAssets() { //load helper setting //var helperSetting = AssetDatabase.LoadAssetAtPath(helperSettingPath); //foreach (var groupDefine in helperSetting.GroupDefines) //{ // groupDefine.CopyToStreamingAssets(); //} AddressableAssetSettings addrSettings = AddressableAssetSettingsDefaultObject.Settings; var groups = addrSettings.groups; foreach (var group in groups) { if (group.Settings.BuildRemoteCatalog) { CopyToStreamingAssets(group, addrSettings); } } AssetDatabase.Refresh(); } private static void CopyToStreamingAssets(AddressableAssetGroup group, AddressableAssetSettings addrSettings) { var buildPath = group.Settings.RemoteCatalogBuildPath; var schema = group.GetSchema(); if (schema != null) { if (schema.BundleMode == BundledAssetGroupSchema.BundlePackingMode.PackSeparately) { foreach (var entry in group.entries) { if (entry.labels.Any(x => x == "pack")) { if (Directory.Exists(buildPath.GetValue(addrSettings)) == false) { Debug.LogError($"{group.name} {entry.address} {buildPath.GetValue(addrSettings)}"); continue; } string bundleName = Path.GetFileName(entry.BundleFileId); if (string.IsNullOrEmpty(bundleName)) { Debug.LogError($"{group.name} {entry.address}"); continue; } var bunldes = Directory.GetFiles(buildPath.GetValue(addrSettings), bundleName); if (bunldes.Length != 1) { Debug.LogError($"{group.name} {entry.address} {bunldes.Length} {bundleName}"); continue; } //copy bundle var dest = Path.Combine(Application.streamingAssetsPath, Path.GetFileName(bunldes[0])); File.Copy(bunldes[0], dest, true); } } } else if (schema.BundleMode == BundledAssetGroupSchema.BundlePackingMode.PackTogether) { foreach (var entry in group.entries) { if (entry.labels.Any(x => x == "pack")) { if (Directory.Exists(buildPath.GetValue(addrSettings)) == false) { Debug.LogError($"{group.name} {entry.address} {buildPath.GetValue(addrSettings)}"); continue; } string bundleName = Path.GetFileName(entry.BundleFileId); if (string.IsNullOrEmpty(bundleName)) { Debug.LogError($"{group.name} {entry.address}"); continue; } var bunldes = Directory.GetFiles(buildPath.GetValue(addrSettings), bundleName); if (bunldes.Length != 1) { Debug.LogError($"{group.name} {entry.address} {bunldes.Length} {bundleName}"); continue; } //copy bundle var dest = Path.Combine(Application.streamingAssetsPath, Path.GetFileName(bunldes[0])); File.Copy(bunldes[0], dest, true); return; } } } else if (schema.BundleMode == BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel) { List names = new List(); foreach (var entry in group.entries) { if (entry.labels.Any(x => x == "pack")) { if (Directory.Exists(buildPath.GetValue(addrSettings)) == false) { Debug.LogError($"{group.name} {entry.address} {buildPath.GetValue(addrSettings)}"); continue; } string bundleName = Path.GetFileName(entry.BundleFileId); if (string.IsNullOrEmpty(bundleName)) { Debug.LogError($"{group.name} {entry.address}"); continue; } if (names.Contains(bundleName)) { continue; } var bunldes = Directory.GetFiles(buildPath.GetValue(addrSettings), bundleName); if (bunldes.Length != 1) { Debug.LogError($"{group.name} {entry.address} {bunldes.Length} {bundleName}"); continue; } names.Add(bundleName); //copy bundle var dest = Path.Combine(Application.streamingAssetsPath, Path.GetFileName(bunldes[0])); File.Copy(bunldes[0], dest, true); } } } } } public static HashSet GetPackFileNames() { var names = new HashSet(); AddressableAssetSettings addrSettings = AddressableAssetSettingsDefaultObject.Settings; var groups = addrSettings.groups; foreach (var group in groups) { if (group.Settings.BuildRemoteCatalog) { GetPackFileNames(group, addrSettings, names); } } return names; } private static void GetPackFileNames(AddressableAssetGroup group, AddressableAssetSettings addrSettings, HashSet names) { var buildPath = group.Settings.RemoteCatalogBuildPath; var schema = group.GetSchema(); if (schema != null) { if (schema.BundleMode == BundledAssetGroupSchema.BundlePackingMode.PackSeparately) { foreach (var entry in group.entries) { if (entry.labels.Any(x => x == "pack")) { if (Directory.Exists(buildPath.GetValue(addrSettings)) == false) { Debug.LogError($"{group.name} {entry.address} {buildPath.GetValue(addrSettings)}"); continue; } string bundleName = Path.GetFileName(entry.BundleFileId); names.Add(bundleName); } } } else if (schema.BundleMode == BundledAssetGroupSchema.BundlePackingMode.PackTogether) { foreach (var entry in group.entries) { if (entry.labels.Any(x => x == "pack")) { if (Directory.Exists(buildPath.GetValue(addrSettings)) == false) { Debug.LogError($"{group.name} {entry.address} {buildPath.GetValue(addrSettings)}"); continue; } string bundleName = Path.GetFileName(entry.BundleFileId); names.Add(bundleName); break; } } } else if (schema.BundleMode == BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel) { foreach (var entry in group.entries) { if (entry.labels.Any(x => x == "pack")) { if (Directory.Exists(buildPath.GetValue(addrSettings)) == false) { Debug.LogError($"{group.name} {entry.address} {buildPath.GetValue(addrSettings)}"); continue; } string bundleName = Path.GetFileName(entry.BundleFileId); if (names.Contains(bundleName)) { continue; } names.Add(bundleName); } } } } } [MenuItem("Window/Asset Management/Helper/Copy All To StreamingAssets")] public static void CopyALLToStreamingAssets() { var addrSettings = AddressableAssetSettingsDefaultObject.Settings; var bundle_dir = addrSettings.RemoteCatalogBuildPath.GetValue(addrSettings); var bunldes = Directory.GetFiles(bundle_dir, $"*.bundle"); foreach (var bunlde in bunldes) { File.Copy(bunlde, bunlde.Replace(bundle_dir, Application.streamingAssetsPath), true); } AssetDatabase.Refresh(); } public static string ExportAssetsFile() { var addrSettings = AddressableAssetSettingsDefaultObject.Settings; var bundle_dir = addrSettings.RemoteCatalogBuildPath.GetValue(addrSettings); var allFileNames = new HashSet(Directory.GetFiles(bundle_dir, $"*.bundle").Select(p => Path.GetFileName(p))); var packFileNanes = GetPackFileNames(); var downloadFileNames = allFileNames.Except(packFileNanes); var bundles = new Dictionary>(); bundles["pack"] = packFileNanes.ToList(); bundles["download"] = downloadFileNames.ToList(); return Newtonsoft.Json.JsonConvert.SerializeObject(bundles, Newtonsoft.Json.Formatting.Indented); } //public static void SyncGroups() //{ //var helperSetting = AssetDatabase.LoadAssetAtPath(helperSettingPath); //var defines = helperSetting.GroupDefines; //var addrSettings = AddressableAssetSettingsDefaultObject.Settings; //foreach (var groupDefine in defines) //{ //var groupName = groupDefine.name; //var group = addrSettings.FindGroup(groupName); //if (null == group) //{ //group = CreateGroup(groupDefine, addrSettings); //} //groupDefine.template.ApplyToAddressableAssetGroup(group); //SyncEntries(groupDefine, group, addrSettings); //EditorUtility.SetDirty(addrSettings); //AssetDatabase.SaveAssets(); //} //var folderDefines = helperSetting.GroupFolderDefines; //foreach (var folderDefine in folderDefines) //{ //var groupName = folderDefine.name; //var group = addrSettings.FindGroup(groupName); //if (null == group) //{ //group = CreateGroupByFolder(groupName, folderDefine, addrSettings); //} //folderDefine.template.ApplyToAddressableAssetGroup(group); //SyncEntriesByFolder(folderDefine, group, addrSettings); //EditorUtility.SetDirty(addrSettings); //AssetDatabase.SaveAssets(); //} //} //[MenuItem("Window/Asset Management/Helper/Sync Groups PreloadOrPack", true)] //static bool ValidateSyncGroupsPRLabel() => IsSettingExists(); //[MenuItem("Window/Asset Management/Helper/Sync Groups PreloadOrPack")] //public static void SyncGroupsPRLabel() //{ //var helperSetting = AssetDatabase.LoadAssetAtPath(helperSettingPath); //var defines = helperSetting.GroupDefines; //var addrSettings = AddressableAssetSettingsDefaultObject.Settings; //foreach (var groupDefine in defines) //{ //var groupName = groupDefine.name; //var group = addrSettings.FindGroup(groupName); //if (null != group) //{ //foreach (var item in groupDefine.labels) //{ //group.entries.ToList().ForEach(x => x.SetLabel(item.labelString, true, true)); //} //} //} //EditorUtility.SetDirty(addrSettings); //AssetDatabase.SaveAssets(); //} //[MenuItem("Window/Asset Management/Helper/Sync Groups RewardLabel", true)] //static bool ValidateSyncGroupsRewardLabel() => IsSettingExists(); //[MenuItem("Window/Asset Management/Helper/Sync Groups RewardLabel")] //public static void SyncGroupsRewardLabel() //{ //var helperSetting = AssetDatabase.LoadAssetAtPath(helperSettingPath); //var defines = helperSetting.GroupDefines; //var addrSettings = AddressableAssetSettingsDefaultObject.Settings; //foreach (var groupDefine in defines) //{ //var groupName = groupDefine.name; //var group = addrSettings.FindGroup(groupName); //if (null != group) //{ //foreach (var item in groupDefine.rewardLabels) //{ //group.entries.ToList().ForEach(x => x.SetLabel(item.labelString, false, true)); //} //} //} //EditorUtility.SetDirty(addrSettings); //AssetDatabase.SaveAssets(); //} } }