AssetBundleMap.cs 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  1. using System;
  2. using UnityEngine;
  3. using UnityEditor;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Security.Cryptography;
  9. using Game.Config;
  10. /// <summary>
  11. /// 构建ab包
  12. /// </summary>
  13. public class AssetBundleMap : EditorWindow
  14. {
  15. /// <summary>
  16. /// shader都打入这个包
  17. /// </summary>
  18. private const string ShaderAbName = "shader.unity3d";
  19. /// <summary>
  20. /// 材质球都打入这个包
  21. /// </summary>
  22. private const string MatAbName = "mat.unity3d";
  23. /// <summary>
  24. /// 临时ab生成目录
  25. /// </summary>
  26. private static readonly string TempAssetBundlePath = Application.dataPath + "/../assetbundle";
  27. private static readonly string TempAssetBundleBakPath = Application.dataPath + "/../assetbundleBak";
  28. private static readonly string DefaultBakDirPath = "Default";
  29. private static readonly string ManifestFileExtension = ".manifest";
  30. /// <summary>
  31. /// 使用lz4压缩
  32. /// </summary>
  33. private static readonly BuildAssetBundleOptions BuildOptions = BuildAssetBundleOptions.DeterministicAssetBundle |
  34. BuildAssetBundleOptions.ChunkBasedCompression;
  35. /// <summary>
  36. /// 构建全部资源
  37. /// </summary>
  38. [MenuItem("AssetBundle/BuildMap/BuildAllAssetBundles")]
  39. public static void BuildAllAssetBundles(VersionCode resVersionCode)
  40. {
  41. Debug.Log("<color=green>================ BuildAllAssetBundles Start================</color>");
  42. AssetDatabase.Refresh();
  43. copyBakAssetsToAssetBundle();
  44. AssetBundleUtil.CleanUnusedAB();
  45. var buildMap = getAllBuildMap(true);
  46. var abm = BuildPipeline.BuildAssetBundles(TempAssetBundlePath, buildMap, BuildOptions,
  47. EditorUserBuildSettings.activeBuildTarget);
  48. if (abm != null)
  49. {
  50. AssetBundleUtil.GetAllAssetsNameInAssetBundle(abm, resVersionCode);
  51. copyAssetBundleToBakAssets();
  52. copyBakAssetsToStreamingAssets();
  53. Debug.Log("<color=green>================ BuildAllAssetBundles Success================</color>");
  54. }
  55. else
  56. {
  57. Debug.Log("<color=green>================ BuildAllAssetBundles Fail================</color>");
  58. throw new Pack.PackException("BuildAssetBundles 失败");
  59. }
  60. }
  61. /// <summary>
  62. /// 只打包lua相关的
  63. /// 在只修改了lua代码,但是未修改资源的情况下使用
  64. /// </summary>
  65. [MenuItem("AssetBundle/Build Map/Build Lua AssetBundles")]
  66. public static void BuildLuaAssetBundles(VersionCode resVersionCode)
  67. {
  68. AssetDatabase.Refresh();
  69. copyBakAssetsToAssetBundle();
  70. AssetBundleUtil.CleanUnusedAB();
  71. var buildMap = getLuaBuildMap(true);
  72. var abm = BuildPipeline.BuildAssetBundles(TempAssetBundlePath, buildMap, BuildOptions,
  73. EditorUserBuildSettings.activeBuildTarget);
  74. if (abm == null)
  75. {
  76. throw new Pack.PackException("BuildAssetBundles 失败");
  77. }
  78. AssetBundleUtil.GetAllAssetsNameInAssetBundle(abm, resVersionCode);
  79. copyAssetBundleToBakAssets();
  80. copyBakAssetsToStreamingAssets();
  81. }
  82. private static void copyBakAssetsToAssetBundle()
  83. {
  84. if (Directory.Exists(TempAssetBundlePath))
  85. {
  86. Directory.Delete(TempAssetBundlePath, true);
  87. }
  88. Directory.CreateDirectory(TempAssetBundlePath);
  89. string path = AssetsObscureUtil.GetUniqueValue();
  90. string dirPath;
  91. BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget;
  92. if (!s_AssetbundleSavePaths.ContainsKey(buildTarget))
  93. {
  94. return;
  95. }
  96. if (string.IsNullOrEmpty(path))
  97. {
  98. dirPath = TempAssetBundleBakPath + s_AssetbundleSavePaths[buildTarget] + DefaultBakDirPath;
  99. }
  100. else
  101. {
  102. dirPath = TempAssetBundleBakPath + s_AssetbundleSavePaths[buildTarget] + path;
  103. }
  104. if (!Directory.Exists(dirPath))
  105. {
  106. return;
  107. }
  108. foreach (string file in Directory.GetFiles(dirPath))
  109. {
  110. string fileName = Path.GetFileName(file);
  111. if (fileName == "assetbundle" || Path.GetExtension(file) == ".manifest")
  112. {
  113. string des = Path.Combine(TempAssetBundlePath, fileName);
  114. File.Copy(file, des, true);
  115. }
  116. }
  117. }
  118. private static void copyAssetBundleToBakAssets()
  119. {
  120. string path = AssetsObscureUtil.GetUniqueValue();
  121. string dirPath;
  122. BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget;
  123. if (!s_AssetbundleSavePaths.ContainsKey(buildTarget))
  124. {
  125. return;
  126. }
  127. if (string.IsNullOrEmpty(path))
  128. {
  129. dirPath = TempAssetBundleBakPath + s_AssetbundleSavePaths[buildTarget] + DefaultBakDirPath;
  130. }
  131. else
  132. {
  133. dirPath = TempAssetBundleBakPath + s_AssetbundleSavePaths[buildTarget] + path;
  134. }
  135. if (!Directory.Exists(dirPath))
  136. {
  137. Directory.CreateDirectory(dirPath);
  138. }
  139. foreach (string file in Directory.GetFiles(TempAssetBundlePath))
  140. {
  141. string fileName = Path.GetFileName(file);
  142. string des = Path.Combine(dirPath, fileName);
  143. File.Copy(file, des, true);
  144. }
  145. }
  146. /// <summary>
  147. /// 拷贝打包好的资源到目标目录
  148. /// </summary>
  149. private static void copyBakAssetsToStreamingAssets()
  150. {
  151. string path = string.Empty;
  152. if (Directory.Exists(Application.streamingAssetsPath))
  153. {
  154. foreach (var item in s_AssetbundleSavePaths)
  155. {
  156. path = Application.streamingAssetsPath + item.Value;
  157. DeleteDirectoryAssets(path, true);
  158. }
  159. }
  160. BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget;
  161. if (!s_AssetbundleSavePaths.ContainsKey(buildTarget))
  162. {
  163. return;
  164. }
  165. string assetBundlePath = Application.streamingAssetsPath + s_AssetbundleSavePaths[buildTarget];
  166. if (!Directory.Exists(assetBundlePath))
  167. {
  168. Directory.CreateDirectory(assetBundlePath);
  169. }
  170. path = AssetsObscureUtil.GetUniqueValue();
  171. string dirPath;
  172. if (string.IsNullOrEmpty(path))
  173. {
  174. dirPath = TempAssetBundleBakPath + s_AssetbundleSavePaths[buildTarget] + DefaultBakDirPath;
  175. }
  176. else
  177. {
  178. dirPath = TempAssetBundleBakPath + s_AssetbundleSavePaths[buildTarget] + path;
  179. }
  180. // 拷贝临时打包目录中的ab资源到对应的StreamingAssets目录下
  181. foreach (string file in Directory.GetFiles(dirPath))
  182. {
  183. if (Path.GetExtension(file) != ".manifest")
  184. {
  185. string fileName = Path.GetFileName(file);
  186. if (fileName == "assetbundle")
  187. {
  188. fileName = AssetsObscureUtil.GetABFileName(fileName);
  189. LogABName("assetbundle", fileName);
  190. }
  191. else if (fileName == $"{ GetAssetsMappingName()}.bytes")
  192. {
  193. EncryptAssetsmapping(file, Path.Combine(assetBundlePath, fileName));
  194. continue;
  195. }
  196. string des = Path.Combine(assetBundlePath, fileName);
  197. File.Copy(file, des, true);
  198. WriteMeaninglessDataToFile(des);
  199. }
  200. }
  201. AssetDatabase.Refresh();
  202. }
  203. private static object GetAssetsMappingName()
  204. {
  205. #if UNITY_IOS
  206. return "afi";
  207. #else
  208. return "assetsmapping";
  209. #endif
  210. }
  211. private static Dictionary<BuildTarget, string> s_AssetbundleSavePaths = new Dictionary<BuildTarget, string>()
  212. {
  213. {BuildTarget.iOS, "/unityRes/"},
  214. {BuildTarget.Android, "/AssetsAndroid/"},
  215. {BuildTarget.StandaloneWindows64, "/AssetsPC/"},
  216. {BuildTarget.WebGL, "/AssetsPC/"},
  217. };
  218. private static void EncryptAssetsmapping(string destPath, string filePath)
  219. {
  220. byte[] bytes = File.ReadAllBytes(destPath);
  221. byte value;
  222. int length = bytes.Length;
  223. for (int i = 0, iMax = Mathf.FloorToInt(length * 0.5f); i < iMax; i += 2)
  224. {
  225. value = bytes[i];
  226. bytes[i] = bytes[length - i - 1];
  227. bytes[length - i - 1] = value;
  228. }
  229. using (var fs = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
  230. {
  231. fs.Write(bytes, 0, length);
  232. }
  233. }
  234. /// <summary>
  235. /// 这个函数不能适配所有文件大小,理论上来说需要文件小于 (int.MaxValue / 2) byte
  236. /// </summary>
  237. /// <param name="filePath"></param>
  238. private static void WriteMeaninglessDataToFile(string filePath)
  239. {
  240. if (!AssetsObscureUtil.IsObscure()) return;
  241. string fileName = Path.GetFileNameWithoutExtension(filePath);
  242. ulong offset = AssetsObscureUtil.GetABOffset(fileName);
  243. if (offset <= 0) return;
  244. uint offsetMain = (uint)AssetsObscureUtil.GetObscureOffsetMin();
  245. if (offset <= offsetMain) return;
  246. byte[] bytes = File.ReadAllBytes(filePath);
  247. int length = bytes.Length;
  248. if (length <= 0) return;
  249. byte[] offsetBytes = new byte[offset];
  250. Array.Copy(bytes, offsetBytes, offsetMain);
  251. byte[] md5Bytes;
  252. using(var md5 = new MD5CryptoServiceProvider())
  253. {
  254. UTF8Encoding encoding = new UTF8Encoding(false);
  255. md5Bytes = md5.ComputeHash(bytes);
  256. }
  257. uint md5Length = (uint)md5Bytes.Length;
  258. int idx = 0;
  259. for (ulong i = offsetMain + 1,
  260. iMax = (offset - offsetMain);
  261. i < iMax; i++)
  262. {
  263. idx = idx + md5Bytes[i % md5Length];
  264. if (idx >= length - 1)
  265. {
  266. idx = idx - length + 1;
  267. }
  268. offsetBytes[i] = bytes[idx];
  269. }
  270. using (FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite))
  271. {
  272. fs.Write(offsetBytes, 0, (int)offset);
  273. fs.Write(bytes, 0, length);
  274. }
  275. }
  276. private struct AssetMap
  277. {
  278. /// <summary>
  279. /// key => ab name
  280. /// value => asset names
  281. /// </summary>
  282. public Dictionary<string, HashSet<string>> Maps;
  283. /// <summary>
  284. /// 记录重复的情况
  285. /// </summary>
  286. public HashSet<string> AllAssets;
  287. }
  288. public static CheckResWindowInfo GetCheckResWindowInfo()
  289. {
  290. string path = "Assets/Editor/AssetBundle/CheckHotResWindownInfo.asset";
  291. return AssetDatabase.LoadAssetAtPath<CheckResWindowInfo>(path);
  292. }
  293. public static Dictionary<string, LanguageAssetBundleName> GetAbNameCfg()
  294. {
  295. Dictionary<string, LanguageAssetBundleName> ret = new Dictionary<string, LanguageAssetBundleName>();
  296. string path = "Assets/Editor/AssetBundle/abname.csv";
  297. TextAsset ta = AssetDatabase.LoadAssetAtPath<TextAsset>(path);
  298. CsvReader csvReader = new CsvReader(LanguageAssetBundleName.FileName_S(), ta.bytes);
  299. LanguageAssetBundleName.OnCsvLoad(csvReader);
  300. LanguageAssetBundleName.Foreach(it =>
  301. {
  302. ret.Add(it.BaseName, it);
  303. //Debug.Log(it.BaseName);
  304. });
  305. LanguageAssetBundleName.Clear();
  306. return ret;
  307. }
  308. /// <summary>
  309. /// 构建全部资源
  310. /// </summary>
  311. /// <param name="showProcessBar"></param>
  312. /// <returns></returns>
  313. private static AssetBundleBuild[] getAllBuildMap(bool showProcessBar)
  314. {
  315. if (showProcessBar)
  316. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Start...", 0.1f);
  317. AssetMap maps = new AssetMap();
  318. maps.Maps = new Dictionary<string, HashSet<string>>(1024);
  319. maps.AllAssets = new HashSet<string>();
  320. // 增加公共shader
  321. addBuildAssetsCommon(maps, ShaderAbName, Constants.ShaderDir, "*.shader");
  322. addBuildAssetsCommon(maps, ShaderAbName, Constants.ShaderDir, "*.shadervariants");
  323. // font
  324. if (showProcessBar)
  325. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Font...", 0.2f);
  326. addBuildAssetsFonts(maps);
  327. addBuildAssetsCommon(maps, "commonmat.unity3d", Constants.CommonMaterialDir, "*.mat");
  328. // config
  329. if (showProcessBar)
  330. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Config...", 0.3f);
  331. addBuildAssetsCommon(maps, "config.unity3d", Constants.CsvConfig, "*.csv");
  332. addBuildAssetsCommon(maps, "xml.unity3d", Constants.XmlConfig, "*.xml");
  333. // audio
  334. if (showProcessBar)
  335. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Audio...", 0.4f);
  336. addBuildAssetsBGM(maps);
  337. addBuildAssetsCommon(maps, "UI_Audio.unity3d", Constants.UIAudioPath, "*.ogg");
  338. addBuildAssetsCommon(maps, "Fight_Audio.unity3d", Constants.FightAudioPath, "*.ogg");
  339. if (showProcessBar)
  340. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Icons...", 0.5f);
  341. addBuildAssetsIcons(maps);
  342. if (showProcessBar)
  343. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Camera...", 0.6f);
  344. addBuildAssetsCamera(maps);
  345. if (showProcessBar)
  346. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Animator...", 0.65f);
  347. addBuildAssetsAnimator(maps);
  348. if (showProcessBar)
  349. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Actor...", 0.7f);
  350. addBuildAssetsActor(maps);
  351. if (showProcessBar)
  352. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Effect...", 0.75f);
  353. addBuildAssetsEffect(maps);
  354. if (showProcessBar)
  355. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "UI...", 0.8f);
  356. addBuildAssetsUI(maps);
  357. if (showProcessBar)
  358. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Scene...", 0.85f);
  359. addBuildAssetsScene(maps);
  360. if (showProcessBar)
  361. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Lua...", 0.9f);
  362. addBuildAssetsLua(maps);
  363. Dictionary<string, LanguageAssetBundleName> abnamecfg = GetAbNameCfg();
  364. List<AssetBundleBuild> bm = new List<AssetBundleBuild>(maps.Maps.Count);
  365. foreach (var items in maps.Maps)
  366. {
  367. AssetBundleBuild bundle = new AssetBundleBuild();
  368. string abname = AssetsObscureUtil.GetABFileName(items.Key);
  369. CheckResWindowInfo info = GetCheckResWindowInfo();
  370. if (abnamecfg.ContainsKey(abname))
  371. {
  372. if (info.Language == BuildLanguage.cn)
  373. {
  374. bundle.assetBundleName = abnamecfg[abname].BaseName;
  375. }
  376. else
  377. {
  378. bundle.assetBundleName = abnamecfg[abname].En;
  379. }
  380. }
  381. else
  382. {
  383. bundle.assetBundleName = abname;
  384. }
  385. bundle.assetNames = items.Value.ToArray();
  386. LogABName(items.Key,bundle.assetBundleName);
  387. if (bundle.assetNames.Length == 0)
  388. {
  389. Debug.LogWarning(items.Key + " empty assetNames");
  390. continue;
  391. }
  392. bm.Add(bundle);
  393. }
  394. if (showProcessBar)
  395. {
  396. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Finish...", 1f);
  397. EditorUtility.ClearProgressBar();
  398. }
  399. return bm.ToArray();
  400. }
  401. static string[] logNames = new string[] { "font.unity3d", "shader.unity3d", "UITexture_UILanuch.unity3d" , "UITexture_UILoading.unity3d", "UILanuch_uiprefab.unity3d", "UILoading_uiprefab.unity3d", "assetbundle" };
  402. private static void LogABName(string name,string abname)
  403. {
  404. if (logNames.Contains(name))
  405. {
  406. Debug.Log($"=========== 包名:【{name}】 ab包名【{abname}】");
  407. }
  408. else
  409. {
  410. Debug.Log($"包名:【{name}】 ab包名【{abname}】");
  411. }
  412. }
  413. /// <summary>
  414. /// 只构建lua相关的资源
  415. /// </summary>
  416. /// <param name="showProcessBar"></param>
  417. /// <returns></returns>
  418. private static AssetBundleBuild[] getLuaBuildMap(bool showProcessBar)
  419. {
  420. if (showProcessBar)
  421. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Start...", 0.1f);
  422. AssetMap maps = new AssetMap();
  423. maps.Maps = new Dictionary<string, HashSet<string>>();
  424. maps.AllAssets = new HashSet<string>();
  425. if (showProcessBar)
  426. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Lua...", 0.9f);
  427. addBuildAssetsCommon(maps, "config.unity3d", Constants.CsvConfig, "*.csv");
  428. addBuildAssetsLua(maps);
  429. List<AssetBundleBuild> bm = new List<AssetBundleBuild>(maps.Maps.Count);
  430. foreach (var items in maps.Maps)
  431. {
  432. AssetBundleBuild bundle = new AssetBundleBuild();
  433. bundle.assetBundleName = items.Key;
  434. bundle.assetNames = items.Value.ToArray();
  435. LogABName(items.Key, bundle.assetBundleName);
  436. if (bundle.assetNames.Length == 0)
  437. {
  438. Debug.LogWarning(items.Key + " empty assetNames");
  439. continue;
  440. }
  441. bm.Add(bundle);
  442. }
  443. if (showProcessBar)
  444. {
  445. EditorUtility.DisplayProgressBar("Generate Bundle Build Map", "Finish...", 1f);
  446. EditorUtility.ClearProgressBar();
  447. }
  448. bm.Sort(assetBundleBuildSort);
  449. return bm.ToArray();
  450. }
  451. private static AssetBundleBuildSort s_AssetBundleBuildSort = null;
  452. private static AssetBundleBuildSort assetBundleBuildSort
  453. {
  454. get
  455. {
  456. if (s_AssetBundleBuildSort == null)
  457. {
  458. s_AssetBundleBuildSort = new AssetBundleBuildSort();
  459. }
  460. return s_AssetBundleBuildSort;
  461. }
  462. }
  463. private class AssetBundleBuildSort : IComparer<AssetBundleBuild>
  464. {
  465. public int Compare(AssetBundleBuild x, AssetBundleBuild y)
  466. {
  467. return string.Compare(x.assetBundleName, y.assetBundleName);
  468. }
  469. }
  470. #region 处理各个模块的assetbundle
  471. private static void addBuildAssetsCommon(AssetMap maps, string abName, string dir,
  472. string filter)
  473. {
  474. string[] fileList = FileUtils.TraverseAllFiles(dir, filter);
  475. for (int idx = 0; idx < fileList.Length; idx++)
  476. {
  477. string fullPath = fileList[idx];
  478. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  479. if (relativePath.EndsWith(".meta")) continue;
  480. addData(maps, abName, relativePath);
  481. }
  482. }
  483. private static void addData(AssetMap maps, string assetBundleName, string assetName)
  484. {
  485. // 重复资源不能加入;按照资源初始化顺序写入
  486. if (maps.AllAssets.Contains(assetName))
  487. {
  488. return;
  489. }
  490. maps.AllAssets.Add(assetName);
  491. if (!maps.Maps.ContainsKey(assetBundleName))
  492. {
  493. maps.Maps[assetBundleName] = new HashSet<string>();
  494. }
  495. maps.Maps[assetBundleName].Add(assetName);
  496. }
  497. private static void addBuildAssetsFonts(AssetMap maps)
  498. {
  499. string[] fileList = FileUtils.TraverseFiles(Constants.FontDir, "*.*");
  500. for (int idx = 0; idx < fileList.Length; idx++)
  501. {
  502. string fullPath = fileList[idx];
  503. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  504. if (relativePath.Contains(".meta")) continue;
  505. addData(maps, "font.unity3d", relativePath);
  506. }
  507. string[] dirList = Directory.GetDirectories(Constants.FontDir);
  508. for (int idx = 0; idx < dirList.Length; idx++)
  509. {
  510. string fullPath = dirList[idx];
  511. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  512. string abName = relativePath.Replace("Assets/", "").Replace("/", "_") + ".unity3d";
  513. string[] files = FileUtils.TraverseFiles(relativePath, "*.*");
  514. for (int jdx = 0; jdx < files.Length; jdx++)
  515. {
  516. string filePathName = files[jdx];
  517. if (filePathName.Contains(".meta")) continue;
  518. string fileRelativePath = FileUtils.ExtractAssetRelativePath(filePathName);
  519. addData(maps, abName, fileRelativePath);
  520. }
  521. }
  522. }
  523. private static void addBuildAssetsBGM(AssetMap maps)
  524. {
  525. string[] files = FileUtils.TraverseAllFiles(Constants.BGMAudioPath, "*.ogg");
  526. for (int idx = 0; idx < files.Length; idx++)
  527. {
  528. string fullPath = files[idx];
  529. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  530. string abName = FileUtils.RemoveExtension(FileUtils.ExtractPureName(relativePath)) + ".unity3d";
  531. addData(maps, abName, relativePath);
  532. }
  533. }
  534. private static void addBuildAssetsIcons(AssetMap maps)
  535. {
  536. string[] allAbNames = AssetDatabase.GetAllAssetBundleNames();
  537. string[] dirs = Directory.GetDirectories(Constants.IconDir, "*", SearchOption.AllDirectories);
  538. for (int idx = 0; idx < dirs.Length; idx++)
  539. {
  540. string dirName = dirs[idx];
  541. string abName = FileUtils.ExtractPureName(dirName) + "_icons.unity3d";
  542. if (allAbNames.Contains(abName))
  543. {
  544. AssetDatabase.RemoveAssetBundleName(abName, true);
  545. }
  546. string[] files = FileUtils.TraverseAllFiles(dirName, "*.png");
  547. for (int jdx = 0; jdx < files.Length; jdx++)
  548. {
  549. string fullPath = files[jdx];
  550. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  551. addData(maps, abName, relativePath);
  552. string[] dependencyAssets = AssetDatabase.GetDependencies(relativePath);
  553. for (int kdx = 0; kdx < dependencyAssets.Length; kdx++)
  554. {
  555. string dependencyAssetName = dependencyAssets[kdx];
  556. string fileType = dependencyAssetName.Substring(dependencyAssetName.LastIndexOf('.') + 1);
  557. fileType = fileType.ToLower();
  558. if (fileType == "shader")
  559. {
  560. addData(maps, ShaderAbName, dependencyAssetName);
  561. }
  562. else if (fileType == "mat")
  563. {
  564. addData(maps, MatAbName, dependencyAssetName);
  565. }
  566. else if (fileType != "cs")
  567. {
  568. addData(maps, abName, dependencyAssetName);
  569. }
  570. }
  571. }
  572. }
  573. }
  574. private static void addBuildAssetsAnimator(AssetMap maps)
  575. {
  576. string[] dirs = Directory.GetDirectories(Constants.AnimatorPath, "*", SearchOption.AllDirectories);
  577. for (int i = 0; i < dirs.Length; i++)
  578. {
  579. string dirName = dirs[i];
  580. string[] files = FileUtils.TraverseAllFiles(dirName, "*.controller");
  581. for (int idx = 0; idx < files.Length; idx++)
  582. {
  583. string fullPath = files[idx];
  584. string fileName = FileUtils.ExtractPureName(fullPath);
  585. string[] tempList = fileName.Split('_');
  586. string abName = tempList[0] + "_animator.unity3d";
  587. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  588. addData(maps, abName, relativePath);
  589. string[] dependencyAssets = AssetDatabase.GetDependencies(relativePath);
  590. for (int jdx = 0; jdx < dependencyAssets.Length; jdx++)
  591. {
  592. string dependencyAssetName = dependencyAssets[jdx];
  593. string fileType = dependencyAssetName.Substring(dependencyAssetName.LastIndexOf('.') + 1);
  594. fileType = fileType.ToLower();
  595. if (fileType == "shader")
  596. {
  597. addData(maps, ShaderAbName, dependencyAssetName);
  598. }
  599. else if (fileType == "mat")
  600. {
  601. addData(maps, MatAbName, dependencyAssetName);
  602. }
  603. else if (fileType != "cs")
  604. {
  605. addData(maps, abName, dependencyAssetName);
  606. }
  607. }
  608. }
  609. }
  610. }
  611. private static void addBuildAssetsActor(AssetMap maps)
  612. {
  613. string[] dirs = Directory.GetDirectories(Constants.ModelPath, "*", SearchOption.AllDirectories);
  614. for (int i = 0; i < dirs.Length; i++)
  615. {
  616. string dirName = dirs[i];
  617. string abName = FileUtils.ExtractPureName(dirName) + ".unity3d";
  618. string textureABName = FileUtils.ExtractPureName(dirName) + "_texture.unity3d";
  619. string fbxABName = FileUtils.ExtractPureName(dirName) + "_model.unity3d";
  620. string[] files = FileUtils.TraverseAllFiles(dirName, "*.prefab");
  621. for (int idx = 0; idx < files.Length; idx++)
  622. {
  623. string fullPath = files[idx];
  624. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  625. addData(maps, abName, relativePath);
  626. string[] dependencyAssets = AssetDatabase.GetDependencies(relativePath);
  627. for (int jdx = 0; jdx < dependencyAssets.Length; jdx++)
  628. {
  629. string dependencyAssetName = dependencyAssets[jdx];
  630. string fileType = dependencyAssetName.Substring(dependencyAssetName.LastIndexOf('.') + 1);
  631. fileType = fileType.ToLower();
  632. if (fileType == "shader")
  633. {
  634. addData(maps, ShaderAbName, dependencyAssetName);
  635. }
  636. else if (fileType == "mat")
  637. {
  638. addData(maps, MatAbName, dependencyAssetName);
  639. }
  640. else if (fileType == "jpg" || fileType == "png" || fileType == "tga" || fileType == "tif" ||
  641. fileType == "psd")
  642. {
  643. addData(maps, textureABName, dependencyAssetName);
  644. }
  645. else if (fileType == "fbx")
  646. {
  647. addData(maps, fbxABName, dependencyAssetName);
  648. }
  649. else if (fileType != "cs")
  650. {
  651. addData(maps, abName, dependencyAssetName);
  652. }
  653. }
  654. }
  655. }
  656. }
  657. private static void addBuildAssetsCamera(AssetMap maps)
  658. {
  659. string[] files = FileUtils.TraverseAllFiles("Assets/Content/Prefabs/Camera", "*.prefab");
  660. for (int idx = 0; idx < files.Length; idx++)
  661. {
  662. string fullPath = files[idx];
  663. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  664. string abName = "prefab_camera.unity3d";
  665. addData(maps, abName, relativePath);
  666. string[] dependencyAssets = AssetDatabase.GetDependencies(relativePath);
  667. for (int jdx = 0; jdx < dependencyAssets.Length; jdx++)
  668. {
  669. string dependencyAssetName = dependencyAssets[jdx];
  670. string fileType = dependencyAssetName.Substring(dependencyAssetName.LastIndexOf('.') + 1);
  671. fileType = fileType.ToLower();
  672. if (fileType == "shader")
  673. {
  674. addData(maps, ShaderAbName, dependencyAssetName);
  675. }
  676. else if (fileType == "mat")
  677. {
  678. addData(maps, MatAbName, dependencyAssetName);
  679. }
  680. else if (fileType != "cs")
  681. {
  682. addData(maps, abName, dependencyAssetName);
  683. }
  684. }
  685. }
  686. }
  687. private static void addBuildAssetsEffect(AssetMap maps)
  688. {
  689. string effectTextureABName = "effect_texture.unity3d";
  690. string effectAnimABName = "effect_dep.unity3d";
  691. string abName = "effect.unity3d";
  692. string[] dirs = Directory.GetDirectories(Constants.EffectPath, "*", SearchOption.AllDirectories);
  693. for (int idx = 0; idx < dirs.Length; idx++)
  694. {
  695. string dirName = dirs[idx];
  696. string[] fileList = FileUtils.TraverseAllFiles(dirName, "*.prefab");
  697. for (int jdx = 0; jdx < fileList.Length; jdx++)
  698. {
  699. string fullPath = fileList[jdx];
  700. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  701. addData(maps, abName, relativePath);
  702. string[] dependencyAssets = AssetDatabase.GetDependencies(relativePath);
  703. for (int kdx = 0; kdx < dependencyAssets.Length; kdx++)
  704. {
  705. string dependencyAssetName = dependencyAssets[kdx];
  706. string fileType = dependencyAssetName.Substring(dependencyAssetName.LastIndexOf('.') + 1);
  707. fileType = fileType.ToLower();
  708. if (fileType == "shader")
  709. {
  710. addData(maps, ShaderAbName, dependencyAssetName);
  711. }
  712. else if (fileType == "mat")
  713. {
  714. addData(maps, MatAbName, dependencyAssetName);
  715. }
  716. else if (fileType == "jpg" || fileType == "png" || fileType == "tga" || fileType == "tif" ||
  717. fileType == "psd")
  718. {
  719. addData(maps, effectTextureABName, dependencyAssetName);
  720. }
  721. else if (fileType != "cs")
  722. {
  723. addData(maps, effectAnimABName, dependencyAssetName);
  724. }
  725. }
  726. }
  727. }
  728. }
  729. private static void addBuildAssetsUI(AssetMap maps)
  730. {
  731. addBuildAssets3DUIPrefab(maps);
  732. addBuildAssetsUIPrefab(maps);
  733. }
  734. private static void addBuildAssets3DUIPrefab(AssetMap maps)
  735. {
  736. string[] allAbNames = AssetDatabase.GetAllAssetBundleNames();
  737. string[] dirs = Directory.GetDirectories(Constants.UI3DPath, "*", SearchOption.AllDirectories);
  738. for (int idx = 0; idx < dirs.Length; idx++)
  739. {
  740. string dirName = dirs[idx];
  741. string abName = FileUtils.ExtractPureName(dirName) + "_3duiprefab.unity3d";
  742. string textureABName = FileUtils.ExtractPureName(dirName) + "_3duiprefab_texture.unity3d";
  743. if (allAbNames.Contains(abName))
  744. {
  745. AssetDatabase.RemoveAssetBundleName(abName, true);
  746. }
  747. string[] files = FileUtils.TraverseAllFiles(dirName, "*.prefab");
  748. for (int jdx = 0; jdx < files.Length; jdx++)
  749. {
  750. string fullPath = files[jdx];
  751. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  752. addData(maps, abName, relativePath);
  753. string[] dependencyAssets = AssetDatabase.GetDependencies(relativePath);
  754. for (int kdx = 0; kdx < dependencyAssets.Length; kdx++)
  755. {
  756. string dependencyAssetName = dependencyAssets[kdx];
  757. string fileType = dependencyAssetName.Substring(dependencyAssetName.LastIndexOf('.') + 1);
  758. fileType = fileType.ToLower();
  759. if (fileType == "shader")
  760. {
  761. addData(maps, ShaderAbName, dependencyAssetName);
  762. }
  763. else if (fileType == "mat")
  764. {
  765. addData(maps, MatAbName, dependencyAssetName);
  766. }
  767. else if (fileType == "jpg" || fileType == "png" || fileType == "tga" || fileType == "tif" ||
  768. fileType == "psd")
  769. {
  770. addData(maps, textureABName, dependencyAssetName);
  771. }
  772. else if (fileType != "cs")
  773. {
  774. addData(maps, abName, dependencyAssetName);
  775. }
  776. }
  777. }
  778. }
  779. }
  780. private static void addBuildAssetsUIPrefab(AssetMap maps)
  781. {
  782. string[] allAbNames = AssetDatabase.GetAllAssetBundleNames();
  783. string[] dirs = Directory.GetDirectories(Constants.UIPath, "*", SearchOption.AllDirectories);
  784. for (int idx = 0; idx < dirs.Length; idx++)
  785. {
  786. string dirName = dirs[idx];
  787. string dirRelativeName = FileUtils.ExtractAssetRelativePath(dirName);
  788. string abName = "";
  789. if (dirRelativeName == Constants.UICommonPath)
  790. {
  791. abName = "prefabsuicommon.unity3d";
  792. }
  793. else
  794. {
  795. abName = FileUtils.ExtractPureName(dirName) + "_uiprefab.unity3d";
  796. }
  797. if (allAbNames.Contains(abName))
  798. {
  799. AssetDatabase.RemoveAssetBundleName(abName, true);
  800. }
  801. string[] files = FileUtils.TraverseAllFiles(dirName, "*.prefab");
  802. for (int jdx = 0; jdx < files.Length; jdx++)
  803. {
  804. string fullPath = files[jdx];
  805. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  806. addData(maps, abName, relativePath);
  807. string rootParent;
  808. FileUtils.ExtractParent(relativePath, out rootParent);
  809. string[] dependencyAssets = AssetDatabase.GetDependencies(relativePath);
  810. for (int kdx = 0; kdx < dependencyAssets.Length; kdx++)
  811. {
  812. string dependencyAssetName = dependencyAssets[kdx];
  813. string fileType = dependencyAssetName.Substring(dependencyAssetName.LastIndexOf('.') + 1);
  814. fileType = fileType.ToLower();
  815. if (fileType == "shader")
  816. {
  817. addData(maps, ShaderAbName, dependencyAssetName);
  818. }
  819. else if (fileType == "mat")
  820. {
  821. addData(maps, MatAbName, dependencyAssetName);
  822. }
  823. else if (fileType == "jpg" || fileType == "png" || fileType == "tga" || fileType == "tif" ||
  824. fileType == "psd")
  825. {
  826. string parent;
  827. FileUtils.ExtractParent(dependencyAssetName, out parent);
  828. parent = FileUtils.ExtractPureName(parent);
  829. string uiTextureABName = "UITexture_" + parent + ".unity3d";
  830. addData(maps, uiTextureABName, dependencyAssetName);
  831. }
  832. else if (fileType == "prefab")
  833. {
  834. string parent;
  835. FileUtils.ExtractParent(dependencyAssetName, out parent);
  836. if (parent.StartsWith(Constants.UIPath))
  837. {
  838. if (rootParent == parent)
  839. {
  840. addData(maps, abName, dependencyAssetName);
  841. }
  842. }
  843. else
  844. {
  845. addData(maps, abName, dependencyAssetName);
  846. }
  847. }
  848. else if (fileType != "cs")
  849. {
  850. addData(maps, abName, dependencyAssetName);
  851. }
  852. }
  853. }
  854. }
  855. }
  856. private static void addBuildAssetsScene(AssetMap maps)
  857. {
  858. string[] fileList = Directory.GetFiles(Constants.ScenePath, "*.unity", SearchOption.AllDirectories);
  859. for (int idx = 0; idx < fileList.Length; idx++)
  860. {
  861. string fullPath = fileList[idx];
  862. if (fullPath.Contains("UIScene") || fullPath.Contains("meta") || fullPath.Contains("SceneCG") ||
  863. fullPath.Replace('\\', '/').Contains("Scene/Other") || fullPath.Contains("WasteAsset") ||
  864. fullPath.Contains("Building"))
  865. continue;
  866. if (fullPath.Contains("game.unity") || fullPath.Contains("Loading.unity"))
  867. {
  868. continue;
  869. }
  870. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  871. string abName = FileUtils.RemoveExtension(FileUtils.ExtractPureName(relativePath)) + ".unity3d";
  872. addData(maps, abName, relativePath);
  873. string scenePrefabABName =
  874. FileUtils.RemoveExtension(FileUtils.ExtractPureName(relativePath)) + "_prefab.unity3d";
  875. string sceneTextureABName =
  876. FileUtils.RemoveExtension(FileUtils.ExtractPureName(relativePath)) + "_texture.unity3d";
  877. string sceneOtherABName =
  878. FileUtils.RemoveExtension(FileUtils.ExtractPureName(relativePath)) + "_other.unity3d";
  879. string lightmapABName = FileUtils.RemoveExtension(FileUtils.ExtractPureName(relativePath)) + "_lm.unity3d";
  880. string[] dependencyAssets = AssetDatabase.GetDependencies(relativePath);
  881. for (int kdx = 0; kdx < dependencyAssets.Length; kdx++)
  882. {
  883. string dependencyAssetName = dependencyAssets[kdx];
  884. if (dependencyAssetName.Contains("Lightmap-") ||
  885. dependencyAssetName.Contains("LightingData") ||
  886. dependencyAssetName.Contains("ReflectionProbe"))
  887. {
  888. addData(maps, lightmapABName, dependencyAssetName);
  889. }
  890. else if (dependencyAssetName.Contains("PostProcessing") && !dependencyAssetName.Contains(".cs"))
  891. {
  892. if (dependencyAssetName.Contains(".shader"))
  893. {
  894. addData(maps, ShaderAbName, dependencyAssetName);
  895. }
  896. else
  897. {
  898. addData(maps, "PostProcessing.unity3d", dependencyAssetName);
  899. }
  900. }
  901. else
  902. {
  903. string fileType = dependencyAssetName.Substring(dependencyAssetName.LastIndexOf('.') + 1);
  904. fileType = fileType.ToLower();
  905. if (fileType == "shader")
  906. {
  907. addData(maps, ShaderAbName, dependencyAssetName);
  908. }
  909. else if (fileType == "mat")
  910. {
  911. addData(maps, MatAbName, dependencyAssetName);
  912. }
  913. else if (fileType == "prefab")
  914. {
  915. if (dependencyAssetName.Contains("Scenes/Scene_common"))
  916. {
  917. string sCommonAb = "scene_common_prefab.unity3d";
  918. addData(maps, sCommonAb, dependencyAssetName);
  919. }
  920. else
  921. {
  922. addData(maps, scenePrefabABName, dependencyAssetName);
  923. }
  924. }
  925. else if (fileType == "png" || fileType == "tga" || fileType == "jpg" || fileType == "tif" ||
  926. fileType == "psd")
  927. {
  928. if (dependencyAssetName.Contains("Scenes/Scene_common"))
  929. {
  930. string sCommonAb = "scene_common_texture.unity3d";
  931. addData(maps, sCommonAb, dependencyAssetName);
  932. }
  933. else
  934. {
  935. addData(maps, sceneTextureABName, dependencyAssetName);
  936. }
  937. }
  938. else if (fileType != "cs")
  939. {
  940. if (dependencyAssetName.Contains("Scenes/Scene_common"))
  941. {
  942. string sCommonAb = "scene_common_other.unity3d";
  943. addData(maps, sCommonAb, dependencyAssetName);
  944. }
  945. else
  946. {
  947. addData(maps, sceneOtherABName, dependencyAssetName);
  948. }
  949. }
  950. }
  951. }
  952. }
  953. }
  954. #endregion
  955. #region 处理lua文件
  956. private static void addBuildAssetsLua(AssetMap maps)
  957. {
  958. CopyLuaAssets(Constants.LuaDir, Constants.ABLuaDir);
  959. CopyLuaAssets(Constants.LuaLogicDir, Constants.ABLuaLogicDir, true);
  960. CopyLuaAssets(Constants.LuaPbDir, Constants.ABLuaPbDir);
  961. CopyLuaAssets(Constants.PubSec, Constants.ABPubsec);
  962. AssetDatabase.Refresh();
  963. ProcessConfigAndLua(maps);
  964. }
  965. private static void CopyLuaAssets(string sourceDir, string destDir, bool optimize = false)
  966. {
  967. string path = Application.dataPath;
  968. path = path.Replace("Assets", "");
  969. string sourceAbsDir = Path.Combine(path, sourceDir);
  970. string destAbsDir = Path.Combine(path, destDir);
  971. HashSet<string> sourceFiles = getAllFilesPathEX(sourceAbsDir);
  972. HashSet<string> destFiles = getAllFilesPathEX(destAbsDir);
  973. // 删除不再需要的文件
  974. foreach (var destFile in destFiles)
  975. {
  976. string sourceFile = destFile.Replace(destAbsDir, sourceAbsDir);
  977. string fileName = Path.GetExtension(sourceFile);
  978. if (fileName.ToLower() == ".txt")
  979. {
  980. string ext = Path.GetExtension(fileName);
  981. if (s_ValidExtMap.Contains(ext))
  982. {
  983. sourceFile = sourceFile.Remove(sourceFile.Length - 4);
  984. }
  985. }
  986. if (!sourceFiles.Contains(sourceFile))
  987. {
  988. File.Delete(destFile);
  989. string metaFilePath = destFile + ".meta";
  990. if (File.Exists(metaFilePath))
  991. {
  992. File.Delete(metaFilePath);
  993. }
  994. string folder = Path.GetDirectoryName(destFile);
  995. DeleteDirectoryAssets(folder);
  996. }
  997. }
  998. // 替换新文件
  999. foreach (var filePath in sourceFiles)
  1000. {
  1001. string destFilePath = filePath.Replace(sourceAbsDir, destAbsDir);
  1002. string destFolder = Path.GetDirectoryName(destFilePath);
  1003. if (!Directory.Exists(destFolder))
  1004. {
  1005. Directory.CreateDirectory(destFolder);
  1006. }
  1007. destFilePath = destFilePath + ".txt";
  1008. if (!File.Exists(destFilePath))
  1009. {
  1010. File.Copy(filePath, destFilePath, true);
  1011. if (optimize && destFilePath.Contains("_Generate"))
  1012. {
  1013. string[] lines = FileSystem.ReadFileLines(destFilePath);
  1014. List<string> contents = new List<string>(lines);
  1015. for (var i = contents.Count - 1; i >= 0; --i)
  1016. {
  1017. if (contents[i].StartsWith("---@") || contents[i].Equals(""))
  1018. {
  1019. contents.RemoveAt(i);
  1020. }
  1021. }
  1022. File.WriteAllLines(destFilePath, contents.ToArray());
  1023. }
  1024. }
  1025. else
  1026. {
  1027. if (optimize && destFilePath.Contains("_Generate"))
  1028. {
  1029. string[] lines1 = FileSystem.ReadFileLines(filePath);
  1030. List<string> contents = new List<string>(lines1);
  1031. for (var i = contents.Count - 1; i >= 0; --i)
  1032. {
  1033. if (contents[i].StartsWith("---@") || contents[i].Equals(""))
  1034. {
  1035. contents.RemoveAt(i);
  1036. }
  1037. }
  1038. lines1 = contents.ToArray();
  1039. string[] lines2 = FileSystem.ReadFileLines(destFilePath);
  1040. bool diff = (lines1.Length != lines2.Length);
  1041. if (!diff)
  1042. {
  1043. for (var i = lines1.Length - 1; i >= 0; i--)
  1044. {
  1045. if (lines1[i] != lines2[i])
  1046. {
  1047. diff = true;
  1048. continue;
  1049. }
  1050. }
  1051. }
  1052. if (diff)
  1053. File.WriteAllLines(destFilePath, lines1);
  1054. }
  1055. else
  1056. {
  1057. string content1 = File.ReadAllText(filePath);
  1058. string content2 = File.ReadAllText(destFilePath);
  1059. if (content1 != content2)
  1060. {
  1061. File.Copy(filePath, destFilePath, true);
  1062. }
  1063. }
  1064. }
  1065. }
  1066. }
  1067. private static void DeleteDirectoryAssets(string dir, bool forceDelete = false)
  1068. {
  1069. if (!Directory.Exists(dir)) return;
  1070. var ls = Directory.GetFileSystemEntries(dir);
  1071. if (forceDelete || ls == null || ls.Length <= 0)
  1072. {
  1073. Directory.Delete(dir, true);
  1074. if (dir.EndsWith("/") || dir.EndsWith("\\"))
  1075. {
  1076. dir = dir.Substring(0, dir.Length - 1);
  1077. }
  1078. string metaFilePath = dir + ".meta";
  1079. if (File.Exists(metaFilePath))
  1080. {
  1081. File.Delete(metaFilePath);
  1082. }
  1083. string folder = Path.GetDirectoryName(dir);
  1084. DeleteDirectoryAssets(folder);
  1085. }
  1086. }
  1087. private static void CopyLuaAsset(string dir)
  1088. {
  1089. string path = Application.dataPath;
  1090. path = Path.Combine(path.Replace("Assets", ""), dir);
  1091. List<string> files = FileSystem.getAllFilesPathEX(path);
  1092. foreach (string fileName in files)
  1093. {
  1094. string destName = fileName.Insert(fileName.IndexOf("Assets/") + 7, "Content/");
  1095. string destFolder = Path.GetDirectoryName(destName);
  1096. if (!Directory.Exists(destFolder))
  1097. {
  1098. Directory.CreateDirectory(destFolder);
  1099. }
  1100. File.Copy(fileName, destName + ".txt", true);
  1101. if (dir.CompareTo(Constants.LuaLogicDir) == 0 && destName.Contains("_Generate"))
  1102. {
  1103. string[] lines = FileSystem.ReadFileLines(destName + ".txt");
  1104. List<string> contents = new List<string>(lines);
  1105. for (var i = contents.Count - 1; i >= 0; --i)
  1106. {
  1107. if (contents[i].StartsWith("---@") || contents[i].Equals(""))
  1108. {
  1109. contents.RemoveAt(i);
  1110. }
  1111. }
  1112. File.WriteAllLines(destName + ".txt", contents.ToArray());
  1113. }
  1114. }
  1115. }
  1116. static void ProcessConfigAndLua(AssetMap maps)
  1117. {
  1118. string luaABName = Constants.LuaDir.Replace("Assets", "").Replace("Content", "").Replace("/", "").ToLower();
  1119. string luaLogicABName = Constants.LuaLogicDir.Replace("Assets", "").Replace("Content", "").Replace("/", "")
  1120. .ToLower();
  1121. string luaPbABName = Constants.LuaPbDir.Replace("Assets", "").Replace("Content", "").Replace("/", "").ToLower();
  1122. string pubSecABName = Constants.PubSec.Replace("Assets", "").Replace("Content", "").Replace("/", "").ToLower();
  1123. string[] allAbNames = AssetDatabase.GetAllAssetBundleNames();
  1124. if (allAbNames.Contains(luaABName))
  1125. AssetDatabase.RemoveAssetBundleName(luaABName, true);
  1126. if (allAbNames.Contains(luaLogicABName))
  1127. AssetDatabase.RemoveAssetBundleName(luaLogicABName, true);
  1128. if (allAbNames.Contains(luaPbABName))
  1129. AssetDatabase.RemoveAssetBundleName(luaPbABName, true);
  1130. if (allAbNames.Contains(pubSecABName))
  1131. AssetDatabase.RemoveAssetBundleName(pubSecABName, true);
  1132. ProcessConfigAndLua(maps, Constants.ABLuaPbDir, luaPbABName);
  1133. ProcessConfigAndLua(maps, Constants.ABLuaDir, luaABName);
  1134. ProcessConfigAndLua(maps, Constants.ABLuaLogicDir, luaLogicABName);
  1135. ProcessConfigAndLua(maps, Constants.ABPubsec, pubSecABName);
  1136. }
  1137. static void ProcessConfigAndLua(AssetMap maps, string dir, string abName)
  1138. {
  1139. List<string> fileList = FileSystem.getAllFilesPathEX(dir);
  1140. for (int idx = 0; idx < fileList.Count; idx++)
  1141. {
  1142. string fullPath = fileList[idx];
  1143. string relativePath = FileUtils.ExtractAssetRelativePath(fullPath);
  1144. if (relativePath.Contains("/Pb/") && dir != Constants.ABLuaPbDir) continue;
  1145. addData(maps, abName + ".unity3d", relativePath);
  1146. }
  1147. }
  1148. #endregion
  1149. private static HashSet<string> s_ValidExtMap = new HashSet<string>()
  1150. {
  1151. ".prefab", ".txt", ".xml", ".txt", ".lua", ".csv", ".ogg", ".wav", ".ttf", ".bytes", ".pb",
  1152. };
  1153. private static HashSet<string> getAllFilesPathEX(string path, string searchPattern = "*.*", SearchOption searchOption = SearchOption.AllDirectories)
  1154. {
  1155. HashSet<string> all = new HashSet<string>();
  1156. if (!Directory.Exists(path))
  1157. {
  1158. return all;
  1159. }
  1160. string[] allFiles = Directory.GetFiles(path, searchPattern, searchOption);
  1161. for (int j = 0; j < allFiles.Length; ++j)
  1162. {
  1163. string fileName = allFiles[j];
  1164. string ext = Path.GetExtension(fileName);
  1165. if (string.IsNullOrEmpty(ext)) continue;
  1166. ext = ext.ToLower();
  1167. if (s_ValidExtMap.Contains(ext))
  1168. {
  1169. all.Add(fileName.Replace('\\', '/'));
  1170. }
  1171. }
  1172. return all;
  1173. }
  1174. }