AssetBundleSetName.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System.IO;
  6. using System.Security.Cryptography;
  7. using System;
  8. using System.Text.RegularExpressions;
  9. public class AssetBundleSetName : AssetBundlesExport
  10. {
  11. /// <summary>
  12. /// md5集合(名称,md5列表)
  13. /// </summary>
  14. private static Dictionary<string, List<string>> md5Dics = new Dictionary<string, List<string>>();
  15. /// <summary>
  16. /// 资源包后缀
  17. /// </summary>
  18. private static string AssetBundleSuffix = "unity3d";
  19. /// <summary>
  20. /// 是否忽略中文名字的文件
  21. /// </summary>
  22. private static bool ignoreZH = true;
  23. /// <summary>
  24. /// 忽略的图片尺寸
  25. /// </summary>
  26. private static int ignoreSiz = 512;
  27. [MenuItem("Build/Android平台 设置Assetbundle名字并打包(使用自身名字,重复资源自动设置单独Assetbundle名)", false, 100)]
  28. public static void SetAssetBundleLabls_Android()
  29. {
  30. SetAssetBundleLabls(BuildTarget.Android);
  31. }
  32. [MenuItem("Build/Windows平台 设置Assetbundle名字并打包(使用自身名字,重复资源自动设置单独Assetbundle名)", false, 200)]
  33. public static void SetAssetBundleLabls_Windows()
  34. {
  35. SetAssetBundleLabls(BuildTarget.StandaloneWindows);
  36. }
  37. //[MenuItem("Build/设置Assetbundle名字并打包 iOS平台 (使用自身名字,重复资源自动设置单独Assetbundle名)")]
  38. //public static void SetAssetBundleLabls_iOS()
  39. //{
  40. // SetAssetBundleLabls(BuildTarget.iOS);
  41. //}
  42. public static void SetAssetBundleLabls(BuildTarget buildTarget)
  43. {
  44. // 移除没有用的assetbundlename
  45. AssetDatabase.RemoveUnusedAssetBundleNames();
  46. md5Dics.Clear();
  47. int index = 0;
  48. //或取出Assets/Bundle所有prefab的guid
  49. string[] prefabPaths = AssetDatabase.FindAssets("t:Prefab t:TextAsset t:ExternalBehaviorTree t:SceneAsset", new string[] { "Assets/Bundle" });
  50. foreach (var prefabGuid in prefabPaths)
  51. {
  52. string prefabAssetPath = AssetDatabase.GUIDToAssetPath(prefabGuid);
  53. string prefabName = Path.GetFileNameWithoutExtension(prefabAssetPath);
  54. index++;
  55. //编辑器进度条
  56. EditorUtility.DisplayProgressBar("处理中>>>", prefabAssetPath, index / (float)prefabPaths.Length);
  57. // 是否忽略带中文的文件
  58. if (ignoreZH)
  59. {
  60. bool hasZH = false;
  61. // 正则表达式检测是否有中文
  62. for (int i = 0; i < prefabName.Length; i++)
  63. {
  64. if (Regex.IsMatch(prefabName[i].ToString(), @"[\u4E00-\u9FA5]+$"))
  65. {
  66. hasZH = true;
  67. break;
  68. }
  69. }
  70. if (hasZH)
  71. {
  72. continue;
  73. }
  74. }
  75. // 先设置Prefab打包名称
  76. AssetImporter prefabImporter = AssetImporter.GetAtPath(prefabAssetPath);
  77. prefabImporter.SetAssetBundleNameAndVariant(prefabName, AssetBundleSuffix);
  78. // 在设置相同引用的资源打包名称
  79. string[] depend = AssetDatabase.GetDependencies(prefabAssetPath, false);
  80. for (int i = 0; i < depend.Length; i++)
  81. {
  82. string assetPath = depend[i];
  83. AssetImporter importer = AssetImporter.GetAtPath(assetPath);
  84. bool ignoreFile = true;
  85. bool aloneFile = false;
  86. // 筛选图片加载器
  87. if (importer is TextureImporter)
  88. {
  89. aloneFile = true;
  90. TextureImporter textureImporter = importer as TextureImporter;
  91. int w, h;
  92. textureImporter.GetSourceTextureWidthAndHeight(out w, out h);
  93. // 图片宽或者高大于等于2048像素才不忽略
  94. if (w >= 2048 || h >= 2048)
  95. {
  96. ignoreFile = false;
  97. }
  98. }
  99. // 筛选模型加载器
  100. else if (importer is ModelImporter)
  101. {
  102. aloneFile = true;
  103. ignoreFile = false;
  104. }
  105. else
  106. {
  107. aloneFile = false;
  108. }
  109. // 独立检测文件
  110. if (aloneFile)
  111. {
  112. string m5 = GetMD5Hash(Path.Combine(Directory.GetCurrentDirectory(), assetPath));
  113. if (md5Dics.ContainsKey(assetPath))
  114. {
  115. if (md5Dics[assetPath].Contains(m5))
  116. {
  117. for (int j = 0; j < md5Dics[assetPath].Count; j++)
  118. {
  119. if (md5Dics[assetPath][j] == m5)
  120. {
  121. if (ignoreFile == false)
  122. {
  123. string fileName = Path.GetFileNameWithoutExtension(assetPath) + j.ToString();
  124. importer.SetAssetBundleNameAndVariant(fileName, AssetBundleSuffix);
  125. Debug.Log("含有相同文件" + assetPath);
  126. }
  127. else
  128. {
  129. //Debug.Log("含有相同文件,但文件太小,直接忽略" + assetPath);
  130. }
  131. }
  132. }
  133. }
  134. else
  135. {
  136. md5Dics[assetPath].Add(m5);
  137. }
  138. }
  139. else
  140. {
  141. List<string> md5s = new List<string>();
  142. md5s.Add(m5);
  143. md5Dics.Add(assetPath, md5s);
  144. }
  145. }
  146. }
  147. }
  148. // 移除没有用的assetbundlename
  149. AssetDatabase.RemoveUnusedAssetBundleNames();
  150. // 编辑器刷新
  151. AssetDatabase.Refresh();
  152. // 清理进度条
  153. EditorUtility.ClearProgressBar();
  154. // 如果存放目录不存在,就创建一个目录
  155. string targetPath = Application.dataPath + "/StreamingAssets/NewRes";
  156. if (!Directory.Exists(targetPath))
  157. {
  158. Directory.CreateDirectory(targetPath);
  159. }
  160. BuildPipeline.BuildAssetBundles(targetPath, BuildAssetBundleOptions.ChunkBasedCompression, buildTarget);
  161. // 编辑器刷新
  162. AssetDatabase.Refresh();
  163. // 完成弹窗
  164. EditorUtility.DisplayDialog("成功", "打包处理完成!", "好的");
  165. }
  166. [MenuItem("Build/清空Assetbundle名字")]
  167. public static void ClearAssetBundleLabls()
  168. {
  169. // 移除没有用的assetbundlename
  170. AssetDatabase.RemoveUnusedAssetBundleNames();
  171. md5Dics.Clear();
  172. int index = 0;
  173. //或取出Assets/Bundle所有prefab的guid
  174. string[] prefabPaths = AssetDatabase.FindAssets("t:Prefab t:TextAsset t:ExternalBehaviorTree", new string[] { "Assets/Bundle" });
  175. foreach (var prefabGuid in prefabPaths)
  176. {
  177. string prefabAssetPath = AssetDatabase.GUIDToAssetPath(prefabGuid);
  178. string prefabName = Path.GetFileNameWithoutExtension(prefabAssetPath);
  179. index++;
  180. //编辑器进度条
  181. EditorUtility.DisplayProgressBar("处理中>>>", prefabAssetPath, index / (float)prefabPaths.Length);
  182. // 是否忽略带中文的文件
  183. if (ignoreZH)
  184. {
  185. bool hasZH = false;
  186. // 正则表达式检测是否有中文
  187. for (int i = 0; i < prefabName.Length; i++)
  188. {
  189. if (Regex.IsMatch(prefabName[i].ToString(), @"[\u4E00-\u9FA5]+$"))
  190. {
  191. hasZH = true;
  192. break;
  193. }
  194. }
  195. if (hasZH)
  196. {
  197. continue;
  198. }
  199. }
  200. // 先设置Prefab打包名称
  201. AssetImporter prefabImporter = AssetImporter.GetAtPath(prefabAssetPath);
  202. prefabImporter.SetAssetBundleNameAndVariant("", "");
  203. // 在设置相同引用的资源打包名称
  204. string[] depend = AssetDatabase.GetDependencies(prefabAssetPath, false);
  205. for (int i = 0; i < depend.Length; i++)
  206. {
  207. string assetPath = depend[i];
  208. AssetImporter importer = AssetImporter.GetAtPath(assetPath);
  209. importer.SetAssetBundleNameAndVariant("", "");
  210. }
  211. }
  212. // 移除没有用的assetbundlename
  213. AssetDatabase.RemoveUnusedAssetBundleNames();
  214. // 编辑器刷新
  215. AssetDatabase.Refresh();
  216. // 清理进度条
  217. EditorUtility.ClearProgressBar();
  218. // 完成弹窗
  219. EditorUtility.DisplayDialog("成功", "清理处理完成!", "好的");
  220. }
  221. /// <summary>
  222. ///获取⽂件Md5
  223. /// </summary>
  224. /// <returns>Md5 hash.</returns>
  225. /// <param name="filePath">File path.</param>
  226. static string GetMD5Hash(string filePath)
  227. {
  228. MD5 md5 = new MD5CryptoServiceProvider();
  229. return BitConverter.ToString(md5.ComputeHash(File.ReadAllBytes(filePath))).Replace("-", "").ToLower();
  230. }
  231. }