using System; using System.CodeDom; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; using UnityEditor; using UnityEngine; namespace IcecreamView.Editor { public static class IceCreamCodeUtils { public const string Templete = @"using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using IcecreamView; #NamespaceStart public class #ScriptName : #Abstract { public override void OnOpenView(IC_ViewData parameters) { } public override void OnCloseView() { } } #NamespaceEnd "; public const string UIPanelTemplete = @" using IcecreamView; #NamespaceStart public class UIPanel { //Code start //Code end } #NamespaceEnd "; public static void CreateCode(SerializedObject target) { if (target.targetObject == null || string.IsNullOrEmpty(target.targetObject.name)) { return; } // CodeCompileUnit unit = new CodeCompileUnit(); // //设置命名空间(这个是指要生成的类的空间) // CodeNamespace myNamespace = new CodeNamespace("Joh.Test"); // //导入必要的命名空间引用 // myNamespace.Imports.Add(new CodeNamespaceImport("System")); // myNamespace.Imports.Add(new CodeNamespaceImport("UnityEngine")); // //Code:代码体 // CodeTypeDeclaration myClass = new CodeTypeDeclaration(className); string className = string.IsNullOrEmpty(GlobalInstance.NameSpacePath) ? target.targetObject.name : GlobalInstance.NameSpacePath + "." + target.targetObject.name; string objPath = GetGameObjectPath(((IC_ModuleConnector) target.targetObject).transform); WriteFile("Temp", "ICE_ACTION.tmp", StringToArrayByteUtf8(className + "#" + objPath)); string path = $"Assets/{GlobalInstance.FilePath ?? "Scripts/View"}"; string fileName = $"{target.targetObject.name.Replace(" ", "")}.cs"; if (!File.Exists(path + "/" + fileName)) { //创建代码 string fileContent = Templete; if (string.IsNullOrEmpty(GlobalInstance.NameSpacePath) == false) { fileContent = fileContent.Replace("#NamespaceStart", $"namespace {GlobalInstance.NameSpacePath}" + "{"); fileContent = fileContent.Replace("#NamespaceEnd", "}"); } else { fileContent = fileContent.Replace("#NamespaceStart", ""); fileContent = fileContent.Replace("#NamespaceEnd", ""); } fileContent = fileContent.Replace("#Abstract", GlobalInstance.AbstractClass ?? "IC_AbstractModule"); fileContent = fileContent.Replace("#ScriptName", target.targetObject.name); WriteFile(path, fileName, StringToArrayByteUtf8(fileContent)); Debug.Log("构建UI代码完成:" + path + "/" + fileName); UpdateUIPanel(target.targetObject.name.Replace(" ", "")); AssetDatabase.Refresh(); } else { // Debug.Log("已存在相同文件名:" + path + "/" + fileName); BindComponent(); } } // // [MenuItem("Icecream/UpdatePanel")] // public static void MainTest() // { // UpdateUIPanel("Test"); // } /// /// 更新UIPanel /// public static void UpdateUIPanel(String name) { var path = GlobalInstance.FilePath; var fileName = "UIPanel.cs"; if (!File.Exists("Assets/" + path + "/" + fileName)) { CreateUIPanel(); } var fileContent = ReadFile("Assets/" + path, fileName); // Debug.Log(fileContent); var startIndex = fileContent.IndexOf("//Code start", StringComparison.Ordinal) + 13; var endIndex = fileContent.IndexOf("//Code end", StringComparison.Ordinal) - 10; var panelContent = fileContent.Substring(startIndex , endIndex - startIndex); // Debug.Log(panelContent); var panelList = panelContent.Split(';'); List panelNames = new List(); var temp = "public const string "; bool isCreate = true; foreach (var panel in panelList) { var start = panel.IndexOf(temp, StringComparison.Ordinal); if (start > 0) { var p2 = panel.Substring(start + temp.Length); var panelName = p2.Substring(0, p2.IndexOf(" ", StringComparison.Ordinal)); panelNames.Add(panelName); if (panelName.Equals(name , StringComparison.Ordinal)) { isCreate = false; } } } if (isCreate) { //添加新Panel fileContent = fileContent.Insert(endIndex, $"\r\n {temp}{name} \t\t\t=\"{name}\";"); Debug.Log("构建UIPanel完成: " + name); } // Debug.Log(fileContent); WriteFile("Assets/"+path, fileName, StringToArrayByteUtf8(fileContent)); } public static void CreateUIPanel() { var path = "Assets/" + GlobalInstance.FilePath; var fileName = "UIPanel.cs"; // if (File.Exists(path + "/" + fileName)) // { // File.Delete(path + "/" + fileName); // } var fileContent = UIPanelTemplete; if (string.IsNullOrEmpty(GlobalInstance.NameSpacePath) == false) { fileContent = fileContent.Replace("#NamespaceStart", $"namespace {GlobalInstance.NameSpacePath}" + "{"); fileContent = fileContent.Replace("#NamespaceEnd", "}"); } else { fileContent = fileContent.Replace("#NamespaceStart", ""); fileContent = fileContent.Replace("#NamespaceEnd", ""); } WriteFile(path, fileName, StringToArrayByteUtf8(fileContent)); } [UnityEditor.Callbacks.DidReloadScripts] public static void BindComponent() { if (File.Exists("Temp/ICE_ACTION.tmp") == false) { return; } string fileContent = ReadFile("Temp", "ICE_ACTION.tmp"); File.Delete("Temp/ICE_ACTION.tmp"); string className = fileContent.Substring(0, fileContent.IndexOf("#", StringComparison.Ordinal)); string objPath = fileContent.Substring(fileContent.IndexOf("#", StringComparison.Ordinal) + 1); var assembly = Assembly.Load(GlobalInstance.AssemblyName); if (assembly == null) { Debug.LogError("加载失败:" + GlobalInstance.AssemblyName); return; } Type t = assembly.GetType(className); var obj = GameObject.Find(objPath); if (t != null) { if (!obj.GetComponent(t)) { obj.gameObject.AddComponent(t); } var prefabPath = "Assets/" + GlobalInstance.PrefabsPath + "/" + obj.name + ".prefab"; if (Directory.Exists("Assets/" + GlobalInstance.PrefabsPath) == false) { Directory.CreateDirectory("Assets/" + GlobalInstance.PrefabsPath); } if (File.Exists(prefabPath)) { //保存修改到预制体 PrefabUtility.ApplyPrefabInstance(obj, InteractionMode.AutomatedAction); } else { //创建预制体 PrefabUtility.SaveAsPrefabAssetAndConnect(obj, prefabPath, InteractionMode.AutomatedAction); } Debug.Log("构建UI预制体完成:" + prefabPath); AssetDatabase.Refresh(); } } private static string GetGameObjectPath(Transform obj) { Transform selectChild = obj; string result = selectChild.name; if (selectChild != null) { while (selectChild.parent != null) { selectChild = selectChild.parent; result = string.Format("{0}/{1}", selectChild.name, result); } } return result; // Debug.Log(string.Format("The gameobject:{0}'s path has been copied to the clipboard!", obj.name)); } private static IC_GlobalSetting _globalInstance; public static IC_GlobalSetting GlobalInstance { get { if (_globalInstance == null) { #if UNITY_EDITOR _globalInstance = AssetDatabase.LoadAssetAtPath("Assets/IceCreamGlobalSettings.asset"); if (_globalInstance == null) { _globalInstance = ScriptableObject.CreateInstance(); // 自定义资源保存路径 string path = "Assets/"; //如果项目总不包含该路径,创建一个 if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } AssetDatabase.CreateAsset(_globalInstance, path + "/IceCreamGlobalSettings.asset"); AssetDatabase.Refresh(); _globalInstance = AssetDatabase.LoadAssetAtPath("Assets/IceCreamGlobalSettings.asset"); } #endif } return _globalInstance; } } public static void WriteFile(string path, string fileName, byte[] content) { CreateDirectory(path); var fullName = path + "/" + fileName; FileStream fs = new FileStream(fullName, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.None); fs.Write(content, 0, content.Length); fs.Close(); } public static void CreateDirectory(string path) { if (!(Directory.Exists(path) || File.Exists(path))) { Directory.CreateDirectory(path); } } public static string ReadFile(string path, string fileName) { var fullName = path + "/" + fileName; if (Directory.Exists(path) || File.Exists(path)) { FileStream fs = new FileStream(fullName, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.None); byte[] bytes = new byte[fs.Length]; fs.Read(bytes, 0, bytes.Length); fs.Close(); return ArrayByteUtf8ToString(bytes); } return null; } public static byte[] StringToArrayByteUtf8(string value) { return Encoding.UTF8.GetBytes(value); } public static string ArrayByteUtf8ToString(byte[] bytes) { return Encoding.UTF8.GetString(bytes); } } }