代码如下:
1 using System.Linq; 2 using System.IO; 3 using UnityEditor; 4 using UnityEditor.AddressableAssets; 5 using UnityEditor.AddressableAssets.Settings; 6 using UnityEngine; 7 using System; 8 using AssetBundle; 9 using System.Collections.Generic; 10 using System.Text.RegularExpressions; 11 using UObject = UnityEngine.Object; 12 13 public class AddressableGroupSetter : ScriptableObject 14 { 15 static AddressableAssetSettings Settings 16 { 17 get { return AddressableAssetSettingsDefaultObject.Settings; } 18 } 19 20 21 [MenuItem("Test/Reset Groups")] 22 static void ResetGroups() 23 { 24 // ui 25 ResetGroup<GameObject>("ui_prefab", "Assets/UI/Prefab/", "f:*.prefab", assetPath => 26 { 27 string fileName = Path.GetFileNameWithoutExtension(assetPath); 28 string dirPath = Path.GetDirectoryName(assetPath); 29 string dirName = Path.GetFileNameWithoutExtension(dirPath); 30 return $"{dirName}/{fileName}"; 31 }); 32 33 // ... 34 } 35 36 /// <summary> 37 /// 重置某分组 38 /// </summary> 39 /// <typeparam name="T">资源类型</typeparam> 40 /// <param name="groupName">组名</param> 41 /// <param name="assetFolder">资源目录</param> 42 /// <param name="filter">过滤器: 43 /// 若以t:开头,表示用unity的方式过滤; 44 /// 若以f:开头,表示用windows的SearchPattern方式过滤; 45 /// 若以r:开头,表示用正则表达式的方式过滤。</param> 46 /// <param name="getAddress">通过 asset path 得到地址名</param> 47 static void ResetGroup<T>(string groupName, string assetFolder, string filter, Func<string, string> getAddress) 48 { 49 string[] assets = GetAssets(assetFolder, filter); 50 AddressableAssetGroup group = CreateGroup<T>(groupName); 51 foreach (var assetPath in assets) 52 { 53 string address = getAddress(assetPath).ToLower(); 54 AddAssetEntry(group, assetPath, address); 55 } 56 57 Debug.Log($"Reset group finished, group: {groupName}, asset folder: {assetFolder}, filter: {filter}, count: {assets.Length}"); 58 } 59 60 // 创建分组 61 static AddressableAssetGroup CreateGroup<T>(string groupName) 62 { 63 AddressableAssetGroup group = Settings.FindGroup(groupName); 64 if (group == null) 65 group = Settings.CreateGroup(groupName, false, false, false, null, typeof(T)); 66 Settings.AddLabel(groupName, false); 67 return group; 68 } 69 70 // 给某分组添加资源 71 static AddressableAssetEntry AddAssetEntry(AddressableAssetGroup group, string assetPath, string address) 72 { 73 string guid = AssetDatabase.AssetPathToGUID(assetPath); 74 75 AddressableAssetEntry entry = group.entries.FirstOrDefault(e => e.guid == guid); 76 if (entry == null) 77 { 78 entry = Settings.CreateOrMoveEntry(guid, group, false, false); 79 } 80 81 entry.address = address; 82 entry.SetLabel(group.Name, true, false, false); 83 return entry; 84 } 85 86 /// <summary> 87 /// 获取指定目录的资源 88 /// </summary> 89 /// <param name="filter">过滤器: 90 /// 若以t:开头,表示用unity的方式过滤; 91 /// 若以f:开头,表示用windows的SearchPattern方式过滤; 92 /// 若以r:开头,表示用正则表达式的方式过滤。</param> 93 public static string[] GetAssets(string folder, string filter) 94 { 95 if (string.IsNullOrEmpty(folder)) 96 throw new ArgumentException("folder"); 97 if (string.IsNullOrEmpty(filter)) 98 throw new ArgumentException("filter"); 99 100 folder = folder.TrimEnd('/').TrimEnd('\'); 101 102 if (filter.StartsWith("t:")) 103 { 104 string[] guids = AssetDatabase.FindAssets(filter, new string[] { folder }); 105 string[] paths = new string[guids.Length]; 106 for (int i = 0; i < guids.Length; i++) 107 paths[i] = AssetDatabase.GUIDToAssetPath(guids[i]); 108 return paths; 109 } 110 else if (filter.StartsWith("f:")) 111 { 112 string folderFullPath = BuildingBundle.GetFullPath(folder); 113 string searchPattern = filter.Substring(2); 114 string[] files = Directory.GetFiles(folderFullPath, searchPattern, SearchOption.AllDirectories); 115 string[] paths = new string[files.Length]; 116 for (int i = 0; i < files.Length; i++) 117 paths[i] = BuildingBundle.GetAssetPath(files[i]); 118 return paths; 119 } 120 else if (filter.StartsWith("r:")) 121 { 122 string folderFullPath = BuildingBundle.GetFullPath(folder); 123 string pattern = filter.Substring(2); 124 string[] files = Directory.GetFiles(folderFullPath, "*.*", SearchOption.AllDirectories); 125 List<string> list = new List<string>(); 126 for (int i = 0; i < files.Length; i++) 127 { 128 string name = Path.GetFileName(files[i]); 129 if (Regex.IsMatch(name, pattern)) 130 { 131 string p = BuildingBundle.GetAssetPath(files[i]); 132 list.Add(p); 133 } 134 } 135 return list.ToArray(); 136 } 137 else 138 { 139 throw new InvalidOperationException("Unexpected filter: " + filter); 140 } 141 } 142 }
执行菜单 Test/Reset Groups 后效果如下: