/// /// typeof(PoolTest = 需要显示面板的类) /// [CustomEditor(typeof(PoolTest), true)] public class PoolAnalyze_ClassObjectPoolEditor : Editor { public override void OnInspectorGUI() { base.OnInspectorGUI(); GUILayout.BeginHorizontal("box"); GUILayout.Label("类名"); GUILayout.Label("池中数量", GUILayout.Width(50)); GUILayout.Label("常驻数量", GUILayout.Width(50)); GUILayout.EndHorizontal(); if (GameEntry.Pool.ClassObjectPool != null) { foreach (var item in GameEntry.Pool.ClassObjectPool.InspectorDic) { GUILayout.BeginHorizontal("box"); GUILayout.Label(item.Key); GUILayout.Label(item.Value.ToString(), GUILayout.Width(50)); GUILayout.Label("0", GUILayout.Width(50)); GUILayout.EndHorizontal(); } //重绘 Repaint(); } } }
[tabs][tab name="快捷打开工具" active="true"]/********************************************* * YSFramework * 快捷打开工具 * 创建时间：2022/12/28 15:52:23 *********************************************/ using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading; using UnityEditor; using UnityEngine; namespace Framework { /// /// 打开文件/文件夹工具 /// public class OpenFileTools { /// /// 打开文件/文件夹方法 /// /// 文件路径 public static void OpenFile(string path) { Thread newThread = new Thread(new ParameterizedThreadStart(CmdOpenDirectory)); newThread.Start(path); } /// /// 真正打开文件/文件夹的方法 /// private static void CmdOpenDirectory(object obj) { Process p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c start " + obj.ToString(); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; p.Start(); p.WaitForExit(); p.Close(); } [MenuItem("GameObject/打开UI代码", false, 10001)] public static void OpenUIScript() { //选择的对象 var go = Selection.activeGameObject; //脚本路径 var uiRootPath = Application.dataPath + "/GameData/Scripts/UI/"; //文件夹信息 var dirInfo = new DirectoryInfo(uiRootPath); string targetName = string.Empty; //UI打开方式 if (go.name.StartsWith("UI")) { //直接就是脚本名 targetName = go.name.Replace("(Clone)", "") + ".cs"; } //Unit打开方式 if (go.name.EndsWith("Unit")) { var goName = go.name.Replace("(Clone)", "") + ".cs"; //判断是否为独立Unit var parentGo = go.transform.parent; if (parentGo != null && !parentGo.name.StartsWith("Canvas")) { while (!parentGo.name.StartsWith("UI")) { parentGo = parentGo.parent; } //UI名+下划线+Unit名 targetName = parentGo.name + "_" + goName; } else { //默认名+下划线+Unit名 targetName = "Main_" + goName; } } //遍历脚本文件 foreach (var file in dirInfo.GetFileSystemInfos("*.cs", SearchOption.AllDirectories)) { //找到了直接打开 if (file.Name.Equals(targetName)) { OpenFile(file.FullName); UnityEngine.Debug.Log("打开UI代码 ===> " + targetName); return; } } UnityEngine.Debug.LogError("未找到" + go.name + "相关代码"); } } }[/tab][tab name="通过路径定位文件在Project的位置"]var obj = AssetDatabase.LoadMainAssetAtPath(item.Path); //加载文件 if (obj == null) return; EditorGUIUtility.PingObject(obj); //跳转到指定目录 Selection.activeObject = obj; //选择指定文件 [/tab][/tabs]
[tabs][tab name="第一版" active="true"]using System; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; using UnityEngine.UI; using YouYou; namespace JiangHu.Tools { public class CreateUIScriptTool { [MenuItem("Assets/生成UI脚本",false,10000)] //注释看下面Cell public static void CreateUIScript() { var gameObject = Selection.activeGameObject; if (gameObject == null) { GameEntry.LogError("请选中预制体！"); return; } if (!gameObject.name.StartsWith("UI")) { GameEntry.LogError("自动生成代码必须是以UI开头的UI预制体！"); return; } string templateDesignPath = "/Game/YouYouScript/Editor/UITemplateDesign.txt"; string templatePath = "/Game/YouYouScript/Editor/UITemplate.txt"; string prefabPath = "Assets/Download/UI/UIPrefab"; var directoryInfo = new DirectoryInfo(prefabPath); List<GameObject> needBindList = new List<GameObject>(); foreach(var component in gameObject.GetComponentsInChildren<UIBind>()) { needBindList.Add(component.gameObject); } foreach (var file in directoryInfo.GetFileSystemInfos("*", SearchOption.AllDirectories)) { if (file.Extension.Equals(".prefab")) { string name = file.Name.Substring(0, gameObject.name.Length); if (name == gameObject.name) { string scriptDirName = file.FullName.Substring(Application.dataPath.Length + prefabPath.Length - 5); scriptDirName = scriptDirName.Substring(0, scriptDirName.Length - file.Name.Length - 1); string scriptPath = Application.dataPath + "/Game/YouYouScript/UI/" + scriptDirName; if (!Directory.Exists(scriptPath)) { Directory.CreateDirectory(scriptPath); Debug.Log("文件夹创建成功！"); } string scriptStr = GetTemplateDesignText(name, needBindList, templateDesignPath); using (FileStream fs = new FileStream(string.Format("{0}/{1}.Design.cs", scriptPath, name), FileMode.Create)) { using (StreamWriter sw = new StreamWriter(fs)) { sw.Write(scriptStr.ToString()); Debug.Log("绑定关系生成成功！"); } } string scriptName = scriptPath + "/" + name + ".cs"; if (!File.Exists(scriptName)) { scriptStr = GetTemplateText(name, needBindList, templatePath); using (FileStream fs = new FileStream(string.Format("{0}/{1}.cs", scriptPath, name), FileMode.Create)) { using (StreamWriter sw = new StreamWriter(fs)) { sw.Write(scriptStr.ToString()); Debug.Log("业务代码生成成功！仍需手动将代码文件拖到预制体上！"); } } } //回收资源 System.GC.Collect(); //刷新编辑器 AssetDatabase.Refresh(); } } } } /// /// 生成业务代码 /// public static string GetTemplateText(string scriptName, List<GameObject> needBindList, string templatePath) { //读取文本全部内容 string designCode = File.ReadAllText(Application.dataPath + templatePath); //循环添加OnClick方法文本 string btnOnClickStr = string.Empty; foreach (var go in needBindList) { if (go.GetComponent () != null) { btnOnClickStr += " private void OnClick_" + go.name + "()\r\n {\r\n Log(\"点击了" + go.name + "\");\r\n }\r\n"; continue; } } //替换文本 designCode = designCode.Replace("#ClassName", scriptName) .Replace("#BtnOnClick", btnOnClickStr) .Replace("#Time", DateTime.Now.ToString()); return designCode; } /// /// 生成绑定关系 /// public static string GetTemplateDesignText(string scriptName, List<GameObject> needBindList,string templateDesignPath) { //读取文本全部内容 string designCode = File.ReadAllText(Application.dataPath + templateDesignPath); //循环添加组件初始化 组件绑定 按钮绑定 string initComponentStr = string.Empty; string bindComponentStr = string.Empty; string btnOnClickStr = string.Empty; foreach (var go in needBindList) { var bind = go.GetComponent<UIBind>(); var name = go.name; if(bind == null) { continue; } bindComponentStr += " " + name + " = rectTransform.Find(\"" + FindComponentInPrefabPath(scriptName, go) + "\").GetComponent<" + bind.BindComponent.GetType() + ">();\r\n"; initComponentStr += "\r\n /// \r\n /// " + bind.Content + "\r\n /// "; initComponentStr += "\r\n private " + bind.BindComponent.GetType() + " " + name + ";\r\n"; if (go.GetComponent () != null) { btnOnClickStr += " " + name + ".onClick.AddListener(OnClick_" + name + ");\r\n"; } } //替换文本 designCode = designCode.Replace("#ClassName", scriptName) .Replace("#InitComponent", initComponentStr) .Replace("#BindComponent", bindComponentStr) .Replace("#BtnAddOnClick", btnOnClickStr) .Replace("#Time", DateTime.Now.ToString()); return designCode; } /// /// 循环父物体拿到组件路径 /// private static string FindComponentInPrefabPath(string scriptName, GameObject go) { //拿到父物体 修改路径 设置跳出值 var parentGo = go.transform.parent; string path = parentGo.name + "/" + go.name; bool isParent = true; while (isParent) { //如果父物体名字等于传进来的对象名 就退出 if (parentGo.name == scriptName) { isParent = false; break; } //循环添加路径 parentGo = parentGo.transform.parent; path = parentGo.name + "/" + path; } //删除最上级物体名 path = path.Substring(parentGo.name.Length + 1); return path; } [MenuItem("Assets/生成Cell脚本", false, 10000)] public static void CreateCellScript() { //获取选中物体对象 判断是否为Cell var gameObject = Selection.activeGameObject; if (gameObject == null) { GameEntry.LogError("请选中预制体！"); return; } if (!gameObject.name.EndsWith("Cell")) { GameEntry.LogError("自动生成代码必须是以Cell结尾的Cell预制体！"); return; } //模板路径 string templateDesignPath = "/Game/YouYouScript/Editor/TemplateDesignCell.txt"; string templatePath = "/Game/YouYouScript/Editor/TemplateCell.txt"; //UI路径 string prefabPath = "Assets/Download/UI/UIPrefab"; var directoryInfo = new DirectoryInfo(prefabPath); //循环添加绑定组件 List<GameObject> needBindList = new List<GameObject>(); foreach (var component in gameObject.GetComponentsInChildren<UIBind>()) { needBindList.Add(component.gameObject); } //循环找到对应的预制体路径 foreach (var file in directoryInfo.GetFileSystemInfos("*", SearchOption.AllDirectories)) { //找到预制体 if (file.Extension.Equals(".prefab")) { string name = file.Name.Substring(0, gameObject.name.Length); //如果是选中的预制体 if (name == gameObject.name) { //拿到文件夹名字 string scriptDirName = file.FullName.Substring(Application.dataPath.Length + prefabPath.Length - 5); scriptDirName = scriptDirName.Substring(0, scriptDirName.Length - file.Name.Length - 1); //拿到文件夹路径 string scriptPath = Application.dataPath + "/Game/YouYouScript/UI/" + scriptDirName; //如果没有就创建 if (!Directory.Exists(scriptPath)) { Directory.CreateDirectory(scriptPath); Debug.Log(scriptDirName+"文件夹创建成功！"); } //生成绑定关系 string scriptStr = GetTemplateDesignText(name, needBindList, templateDesignPath); using (FileStream fs = new FileStream(string.Format("{0}/{1}.Design.cs", scriptPath, name), FileMode.Create)) { using (StreamWriter sw = new StreamWriter(fs)) { sw.Write(scriptStr.ToString()); Debug.Log("绑定关系生成成功！"); } } //生成业务代码 string scriptName = scriptPath + "/" + name + ".cs"; //如果不存在才创建 if (!File.Exists(scriptName)) { scriptStr = GetTemplateText(name, needBindList, templatePath); using (FileStream fs = new FileStream(string.Format("{0}/{1}.cs", scriptPath, name), FileMode.Create)) { using (StreamWriter sw = new StreamWriter(fs)) { sw.Write(scriptStr.ToString()); Debug.Log("业务代码生成成功！仍需手动将代码拖到预制体上！"); } } } //回收资源 System.GC.Collect(); //刷新编辑器 AssetDatabase.Refresh(); } } } } } } [/tab][tab name="第二版"]using System.IO; using UnityEditor; using UnityEngine; namespace Framework { /// /// UI代码生成 /// public class GenerateUIScript : Editor { [MenuItem("GameObject/Generate UI", false, 10000)] public static void GenerateUI() { var go = Selection.activeGameObject; if (go == null || !go.name.Contains("UI")) { Debug.LogError(go.name + " 不是UI！"); return; } //寻找到当前obj的路径 var directoryInfo = new DirectoryInfo(Application.dataPath); string prefabName = go.name + ".prefab"; string path = string.Empty; foreach (var item in directoryInfo.GetFiles("*.*", SearchOption.AllDirectories)) { if (item.Name == prefabName) { //预制体路径 path = item.FullName; //替换成脚本路径 path = path.Replace("GameData\\Prefabs", "GameData\\Scripts").Substring(0, path.Length - prefabName.Length); break; } } //创建目录 if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } CreateUIScript(go, path); CreateUIDesignScript(go, path); Debug.Log(go.name + "生成完毕！"); //回收资源 System.GC.Collect(); //刷新编辑器 AssetDatabase.Refresh(); } private static void CreateUIScript(GameObject go, string path) { string temp = @"using Framework; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace GameData { public partial class #UIName : UIBase { public override void OnInit() { } public override void OnShow(params object[] args) { } public override void OnBeforDestroy() { } } } "; var scripts = File.CreateText(path + go.name + ".cs"); temp = temp.Replace("#UIName", go.name); scripts.Write(temp); scripts.Close(); } private static void CreateUIDesignScript(GameObject go, string path) { string temp = @"/********************************************* * 自动生成代码，禁止手动修改文件 * 脚本名：#UIName.Design.cs * 修改时间：#Time *********************************************/ using Framework; using UnityEngine; using UnityEngine.UI; namespace GameData { public partial class #UIName : UIBase {#Component public override void OnCreate() { rectTransform = gameobject.GetComponent<RectTransform>(); #Find } } } "; string componentStr = @" /// /// #Remark /// private #Component #Name; "; string FindStr = "#Name = rectTransform.Find(\"#Path\").GetComponent<#Component>();"; var componentArr = go.GetComponentsInChildren<UIBind>(); var newComponentStr = string.Empty; var newFindStr = string.Empty; for (int i = 0; i < componentArr.Length; i++) { //声明变量 var tempComponentStr = componentStr.Replace("#Component", componentArr[i].Obj.GetType().ToString()); tempComponentStr = tempComponentStr.Replace("#Name", componentArr[i].Obj.name); tempComponentStr = tempComponentStr.Replace("#Remark", componentArr[i].Remark); newComponentStr += tempComponentStr; //寻找对象 var tempFindStr = FindStr.Replace("#Component", componentArr[i].Obj.GetType().ToString()); tempFindStr = tempFindStr.Replace("#Name", componentArr[i].Obj.name); tempFindStr = tempFindStr.Replace("#Path", FindComponentInPrefabPath(go.name,componentArr[i].gameObject)); tempFindStr += "\r\n\t\t\t"; newFindStr += tempFindStr; } //创建对象 var scripts = File.CreateText(path + go.name + ".Design.cs"); //文本替换 temp = temp.Replace("#UIName", go.name); temp = temp.Replace("#Time", System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")); temp = temp.Replace("#Component", newComponentStr); temp = temp.Replace("#Find", newFindStr); scripts.Write(temp); scripts.Close(); } /// /// 循环父物体拿到组件路径 /// private static string FindComponentInPrefabPath(string scriptName,GameObject go) { //拿到父物体 修改路径 设置跳出值 var parentGo = go.transform.parent; string path = parentGo.name + "/" + go.name; bool isParent = true; while (isParent) { //如果父物体名字等于传进来的对象名 就退出 if (parentGo.name == scriptName) { isParent = false; break; } //循环添加路径 parentGo = parentGo.transform.parent; path = parentGo.name + "/" + path; } //删除最上级物体名 path = path.Substring(parentGo.name.Length + 1); return path; } } } [/tab][tab name="第三版"]第三版（现在使用的）[/tab][/tabs]
纯代码 没什么好说的using System.IO; using UnityEditor; using UnityEditor.U2D; using UnityEngine; using UnityEngine.U2D; namespace Framework { /// /// 图集生成 /// public class BuildSpriteAtlas : Editor { /// /// 图集磁盘路径 /// public static string SpritePath = Application.dataPath + "/GameData/Art/Sprite"; [MenuItem("YSFramework/Build SpriteAtlas")] public static void BuildAtlas() { Debug.Log("Start Build SpriteAtlas Path=" + SpritePath); var pathDir = new DirectoryInfo(SpritePath); //循环目录下的文件和子目录 但是不包含子目录下的文件和子目录 foreach (var item in pathDir.GetFileSystemInfos("*.*", SearchOption.TopDirectoryOnly)) { var parentDir = item as DirectoryInfo; //空值就代表它是文件 if (parentDir != null) { var file = new FileInfo(parentDir.FullName + "/" + parentDir.Name + ".spriteatlas"); if (file.Exists) { File.Delete(file.FullName); } var atlas = new SpriteAtlas();// 设置参数 可根据项目具体情况进行设置 SpriteAtlasPackingSettings packSetting = new SpriteAtlasPackingSettings() { blockOffset = 1, enableRotation = false, enableTightPacking = false, padding = 2, }; atlas.SetPackingSettings(packSetting); SpriteAtlasTextureSettings textureSetting = new SpriteAtlasTextureSettings() { readable = false, generateMipMaps = false, sRGB = true, filterMode = FilterMode.Bilinear, }; atlas.SetTextureSettings(textureSetting); TextureImporterPlatformSettings platformSetting = new TextureImporterPlatformSettings() { maxTextureSize = 2048, format = TextureImporterFormat.Automatic, crunchedCompression = true, textureCompression = TextureImporterCompression.Compressed, compressionQuality = 50, }; atlas.SetPlatformSettings(platformSetting); var assetPath = "Assets/GameData/Art/Sprite/"; AssetDatabase.CreateAsset(atlas, assetPath + parentDir.Name + "/" + file.Name); // 2、添加文件夹 Object obj = AssetDatabase.LoadAssetAtPath(assetPath + parentDir.Name, typeof(Object)); atlas.Add(new[] { obj }); AssetDatabase.SaveAssets(); } } Debug.Log("Build SpriteAtlas Success!"); //回收资源 System.GC.Collect(); //刷新编辑器 AssetDatabase.Refresh(); } } }
[tabs][tab name="ABConfig：打包配置" active="true"]using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; namespace Framework { // 创建资源AB配置菜单 [CreateAssetMenu(fileName = "ABConfig", menuName = "CreateABConfig", order = 999)] public class ABConfig : ScriptableObject { /// /// 需要打包的文件夹路径，会遍历这个文件夹下的所有文件和文件夹， /// 该目录下的所有文件名和文件夹名不能重复，必须保证名字的唯一性。 /// 直接定位到父目录，用子文件夹名当ab包名，如果根目录有文件用父目录单独打包。 /// [Header("AB包配置根目录（根目录下所有文件夹全部分开打包）")] public List<string> RootABList = new List<string>(); [Header("真正的AB包打包列表(自动生成)")] public List<ABData> TrueABList = new List<ABData>(); [System.Serializable] public class ABData { public string path; public string abName; // ab包名 //public bool must; } /// /// 设置打包名和路径 /// public List<ABData> SetABNameAndPath() { //所有AB包的路径 AB包路径,AB包名 var allABPathList = new List<KeyValuePair<string, string>>(); //需要删除Assets目录之前的Length int needDeleteLength = Application.dataPath.Length - "Assets".Length; //遍历输入的目录 for (int i = 0; i < RootABList.Count; i++) { var rootHasFile = false; var path = RootABList[i]; var pathDir = new DirectoryInfo(path); //循环目录下的文件和子目录 但是不包含子目录下的文件和子目录 foreach (var item in pathDir.GetFileSystemInfos("*.*", SearchOption.TopDirectoryOnly)) { var childDir = item as DirectoryInfo; //空值就代表它是文件 if (childDir == null) { //场景需要单独打包 if (item.Extension == ".unity") { allABPathList.Add(new KeyValuePair<string, string>(item.FullName.Substring(needDeleteLength).Replace("\\", "/"), item.Name.Replace(".unity",""))); } //跳过meta文件 else if (item.Extension != ".meta") { //根目录下也有文件 说明当前路径也需要单独打个包，注意 不要包含其它子文件夹下的文件 rootHasFile = true; } } else //文件夹 { allABPathList.Add(new KeyValuePair<string, string>(item.FullName.Substring(needDeleteLength).Replace("\\", "/"), pathDir.Name + childDir.Name)); } } // 只有在根目录下有文件的时候才会打包根目录 if (rootHasFile) { allABPathList.Add(new KeyValuePair<string, string>(path, pathDir.Name)); } } TrueABList.Clear(); for (int i = 0; i < allABPathList.Count; i++) { var kv = allABPathList[i]; var data = new ABData(); data.path = kv.Key; data.abName = kv.Value.ToLower(); TrueABList.Add(data); } UnityEditor.EditorUtility.SetDirty(this); return TrueABList; } } } [/tab][tab name="ABConfiInspector：打包配置扩展按钮"]using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; namespace Framework { [CustomEditor(typeof(ABConfig))] public class ABConfiInspector : Editor { public override void OnInspectorGUI() { base.OnInspectorGUI(); ABConfig abconfig = target as ABConfig; if (GUILayout.Button("生成真正的AB包列表")) { abconfig.SetABNameAndPath(); } } } } [/tab][tab name="BuildAssetBundle：真正打包的地方"]using LitJson; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEngine; namespace Framework { /// /// AB包生成 /// public class BuildAssetBundles : Editor { /// /// AB包输出路径 /// public static string ABOutPath = Application.dataPath.Substring(0,Application.dataPath .Length - "Assets".Length) + "AssetBundle"; /// /// 脚本DLL输出路径 /// public static string ScriptOutPath = Application.dataPath.Substring(0,Application.dataPath .Length - "Assets".Length) + "HybridCLRData/HotUpdateDlls/" + EditorUserBuildSettings.activeBuildTarget .ToString(); //依赖信息Json路径 private static string JSONINFORMATIONPATH = "Assets/Editor/ABConfig/JsonInformation/AssetInformation.json"; //ABConfig.Asset private static string ABCONFIGPATH = "Assets/Editor/ABConfig/ABConfig.asset"; private static ABConfig _abConfig => AssetDatabase.LoadAssetAtPath<ABConfig>(ABCONFIGPATH); [MenuItem("YSFramework/Build AssetBundles")] public static void BuildAsset() { //1.设置AB包路径和AB包名 _abConfig.SetABNameAndPath(); //2.清空文件夹 if (Directory.Exists(ABOutPath)) { Directory.Delete(ABOutPath, true); } Directory.CreateDirectory(ABOutPath); //3.设置打包名通过路径 SetABNameByPath(); //4.存储依赖关系表（如果用Unity自带的依赖管理可以忽略） SaveABPackageToJson(); //5.真正打ab包的地方，打包实际上就是一句话 BuildPipeline.BuildAssetBundles(ABOutPath, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget); //6.把不需要的依赖文件删除 DeleteRelyOnFile(); //7.生成MD5校验文件 SaveABMD5ToXML(); //8.清除AB包标签 ClearABName(); //打开文件夹 OpenFileTools.OpenFile(ABOutPath); //回收资源 System.GC.Collect(); //刷新编辑器 AssetDatabase.Refresh(); } /// /// 设置AB包路径的AB包名 /// /// private static void SetABNameByPath() { var list = _abConfig.TrueABList; foreach (var item in list) { AssetImporter.GetAtPath(item.path).assetBundleName = item.abName; } } /// /// 存储依赖关系为Json格式 /// private static void SaveABPackageToJson() { Directory.CreateDirectory("Assets/Editor/ABConfig/JsonInformation"); File.Delete(JSONINFORMATIONPATH); var list = _abConfig.TrueABList; var abInfo = new ABInfo(); foreach (var ab in list) { //当前ab包依赖的列表 var relyOnList = AssetDatabase.GetAssetBundleDependencies(ab.abName, true).ToList(); abInfo.ABRelyInfoList.Add(new ABInfo.ABRelyInfo() { ABName = ab.abName, //ABPath = ab.path, ABRelyOnNameList = relyOnList, }); //当前ab包包括的资源路径 foreach (var item in AssetDatabase.GetAssetPathsFromAssetBundle(ab.abName)) { abInfo.ABFileDic.Add(item.Substring(item.LastIndexOf("/") + 1), ab.abName); } } //存储完毕后把这个文件也打个包 读取时首先读取这个AB包 using (var assetInformation = File.CreateText(JSONINFORMATIONPATH)) { assetInformation.Write(JsonMapper.ToJson(abInfo)); } } /// /// 删除不需要的依赖文件 /// private static void DeleteRelyOnFile() { var dir = new DirectoryInfo(ABOutPath); foreach (var item in dir.GetFileSystemInfos("*", SearchOption.AllDirectories)) { if(item.Extension == ".manifest") { File.Delete(item.FullName); } } File.Delete(ABOutPath + "/AssetBundle"); } /// /// 生成AB包的MD5 /// private static void SaveABMD5ToXML() { var list = new List<ABMd5Info>(); var dir = new DirectoryInfo(ABOutPath); foreach (var item in dir.GetFileSystemInfos("*", SearchOption.AllDirectories)) { var path = ABOutPath + "/" + item.Name; list.Add(new ABMd5Info() { ABName = item.Name, ABSize = File.ReadAllBytes(path).Length, ABMd5 = Md5Util.GetMd5ByPath(path), }); } Debug.Log(ScriptOutPath); //添加脚本热更的信息 var dllName = "Assembly-CSharp.dll"; var dllPath = ScriptOutPath + "/" + dllName; list.Add(new ABMd5Info() { ABName = dllName, ABSize = File.ReadAllBytes(dllPath).Length, ABMd5 = Md5Util.GetMd5ByPath(dllPath), }); File.Move(dllPath, ABOutPath + "/" + dllName); //输出资源索引信息 using (var fileUpdateInfo = File.CreateText(ABOutPath + "/" + "fileUpdateInfo.json")) { var json = JsonMapper.ToJson(list); Debug.Log(json); fileUpdateInfo.Write(json); } } /// /// 清除AB包标签 /// private static void ClearABName() { foreach (var item in _abConfig.TrueABList) { AssetImporter.GetAtPath(item.path).assetBundleName = null; } AssetDatabase.RemoveUnusedAssetBundleNames(); foreach (var item in AssetDatabase.GetAllAssetBundleNames()) { Debug.LogError("AB 标签存在未移除情况：" + item); } } } } [/tab][/tabs]