using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System; using System.IO; using ICSharpCode.SharpZipLib.Zip; using System.Text.RegularExpressions; public class AssetBundleBuilder : EditorWindow { static string m_Version = "1.1.1"; static string m_ResourcesPath = "Assets/Resources/"; static BuildTarget m_BuildTarget = BuildTarget.StandaloneWindows64; static List<string> m_IgnoreSuffixs = new List<string> { ".cs", ".shader", ".unity" }; static string m_PlatformPath; static string m_ManifestPath; static string m_AssetBundlePath; [MenuItem("Tools/AssetBundleBuilder")] static void Init() { var window = (AssetBundleBuilder)GetWindow(typeof(AssetBundleBuilder)); window.Show(); } void OnGUI() { GUILayout.Label("AssetBundleBuilder", EditorStyles.boldLabel); EditorGUILayout.LabelField("打包平台", AssetBundleUtil.GetPlatform()); m_Version = EditorGUILayout.TextField("版本号", m_Version); m_BuildTarget = (BuildTarget)EditorGUILayout.EnumPopup("目标平台", m_BuildTarget); m_PlatformPath = "D:/PackProject/AssetBundle/" + m_BuildTarget.ToString(); m_ManifestPath = m_PlatformPath + "/manifest"; m_AssetBundlePath = m_PlatformPath + "/" + m_Version; EditorGUILayout.LabelField("保存路径: ", m_AssetBundlePath); if (GUILayout.Button("Clear Manifest Folder")) ClearStorageFolder(); if (GUILayout.Button("Clear All AssetBundleNames")) ClearAssetBundleName(); if (GUILayout.Button("Build")) Build(); } static void Build() { ClearAssetBundleName(); SetAssetBundleName(); CreateAssetBundle(); MoveAssetBundle(); BuildZipFile(); } static void MoveAssetBundle() { var info = new DirectoryInfo(m_AssetBundlePath); if (info.Exists) info.Delete(true); info.Create(); var index = 0; var assetFolder = new DirectoryInfo(m_ManifestPath); var allFiles = assetFolder.GetFiles("*", SearchOption.AllDirectories); foreach (var file in allFiles) { if (file.FullName.Contains(".manifest")) continue; var name = file.FullName.Replace("\\", "/"); name = name.Replace(m_ManifestPath, ""); var t = m_AssetBundlePath + name; var folder = t.Remove(t.LastIndexOf("/")); var tempfolder = new DirectoryInfo(folder); if (! tempfolder.Exists) tempfolder.Create(); file.MoveTo(t); EditorUtility.DisplayProgressBar("移动文件。。", name, (float)index / allFiles.Length); } EditorUtility.ClearProgressBar(); } static void ClearStorageFolder() { var dirInfo = new DirectoryInfo(m_ManifestPath); if (dirInfo.Exists) dirInfo.Delete(true); } static void BuildZipFile() { var infos = new DirectoryInfo(m_AssetBundlePath); var compressTotal = infos.GetFiles("*.*", SearchOption.AllDirectories).Length; if (compressTotal <= 0) return; var folders = new string[] { m_AssetBundlePath }; var outputZip = m_PlatformPath + "/res_all_" + m_Version + ".zip"; ZipUtility.Zip(folders, outputZip, "aiteachu", new AssetBundleZipCallBack(compressTotal)); EditorUtility.ClearProgressBar(); } static void ClearAssetBundleName() { var names = AssetDatabase.GetAllAssetBundleNames(); var index = 0; foreach (var name in names) { index++; var progress = (float)index / names.Length; EditorUtility.DisplayProgressBar("清除AssetBundle标记", name, progress); AssetDatabase.RemoveAssetBundleName(name, true); } EditorUtility.ClearProgressBar(); } static void SetAssetBundleName() { //SetAssetName(m_ResourcesPath, ".json", false); SetAssetName(m_ResourcesPath, ".playable", false); //SetAssetName(m_ResourcesPath + "UIImage/", ".png", false); //SetAssetName(m_ResourcesPath + "UIImage/", ".jpg", false); //SetAssetName(m_ResourcesPath, ".mat", false); //SetAssetName(m_ResourcesPath, ".prefab", false); //SetAssetName(m_ResourcesPath, ".controller", false); //SetAssetName(m_ResourcesPath, ".unity", false); } static void CreateAssetBundle() { var info = new DirectoryInfo(m_ManifestPath); if (! info.Exists) info.Create(); var option = BuildAssetBundleOptions.ChunkBasedCompression; BuildPipeline.BuildAssetBundles(m_ManifestPath, option, m_BuildTarget); } static void SetAssetName(string resourcesPath, string filter, bool excludeDependences) { var paths = GetPaths(resourcesPath, filter); var index = 0; foreach (var path in paths) { index++; var progress = (float)index / paths.Count; if (!CheckPath(path)) { Debug.LogError("path has error : " + path); continue; } var tempPath = path.Replace("\\", "/"); var name = tempPath.Remove(tempPath.LastIndexOf('.')); SetName(tempPath, name); if (excludeDependences) SetDenpendencesName(tempPath); EditorUtility.DisplayProgressBar("SetName...", path, progress); } EditorUtility.ClearProgressBar(); } // 去除掉不符合命名规则的文件 文件名只包含数字,大小写字符,下滑线 空格 & . - public static bool CheckPath(string path) { var name = Path.GetFileNameWithoutExtension(path); var rex = new Regex(@"^[0-9A-Za-z_&][0-9A-Za-z_\s&.-]*$"); var ma = rex.Match(name); return ma.Success; } static void SetDenpendencesName(string target) { var denpendences = AssetDatabase.GetDependencies(target); foreach (var dependencePath in denpendences) { var extension = Path.GetExtension(dependencePath); if (m_IgnoreSuffixs.Contains(extension)) continue; var name = dependencePath.Remove(dependencePath.LastIndexOf('.')); SetName(dependencePath, name); } } static void SetName(string path, string name) { var import = AssetImporter.GetAtPath(path); if (string.IsNullOrEmpty(import.assetBundleName)) { name = name.Replace(" ", ""); name = name.Replace("-", "_"); import.SetAssetBundleNameAndVariant(name, null); } } static List<string> GetPaths(string dirPath, string suffix) { var ls = new List<string>(); foreach (string path in Directory.GetFiles(dirPath)) { if (Path.GetExtension(path) == suffix) ls.Add(path.Substring(path.IndexOf("Assets"))); } var dirs = Directory.GetDirectories(dirPath); if (dirs.Length > 0) { foreach (string path in dirs) ls.AddRange(GetPaths(path, suffix)); } return ls; } class AssetBundleZipCallBack : ZipUtility.ZipCallback { int m_Index; int m_Total; public AssetBundleZipCallBack(int total) { m_Total = total; } // 压缩单个文件或文件夹后执行的回调 public override void OnPostZip(ZipEntry entry) { m_Index++; var progress = (float)m_Index / m_Total; EditorUtility.DisplayProgressBar("压缩文件夹", entry.Name, progress); } public override void OnFinished(bool result) { m_Index = 0; m_Total = 0; if(result) Debug.Log("======压缩完成========="); else Debug.Log("======压缩失败========="); } } }