using System; using System.IO; using System.Text; using UnityEditor; using UnityEngine; using System.Reflection; namespace Thousandto.DIY { public class CreateForm : EditorWindow { [MenuItem("NGUI/Create/")] public static void AddBreakerForm() { } [MenuItem("NGUI/Create/Form")] public static void AddForm() { CreateForm form = EditorWindow.GetWindow("创建窗体",true); form.minSize = new Vector2(400, 200); form.Show(); } public const string FORM_ROOT_PATH = "Assets/GameAssets/Resources/GameUI/Form/{0}/Prefabs/{1}.prefab"; public const string FORM_SCRIPT_PATH = "Assets/GameAssets/Resources/GameUI/Form/{0}/Scripts/{1}.cs"; //Lua脚本路径 public const string FORM_LUA_SCRIPT_PATH = "Assets/GameAssets/Resources/Lua/UI/Forms/{0}/{1}.lua"; public string[] FORM_TEMPLATE_PREFABS = new string[] { "Assets/GameAssets/Resources/Temp/Template/UITemplate.prefab", "Assets/GameAssets/Resources/Temp/Template/UINullTemplate.prefab", "Assets/GameAssets/Resources/Temp/Template/UIDialogTemplate.prefab", }; public string[] FORM_TEMPLATE_SCRIPTS = new string[] { "Assets/GameAssets/Resources/Temp/Template/UITemplate.cs", "Assets/GameAssets/Resources/Temp/Template/UINullTemplate.cs", "Assets/GameAssets/Resources/Temp/Template/UIDialogTemplate.cs", }; //lua示例脚本 public string[] FORM_TEMPLATE_LUA_SCRIPTS = new string[] { "Assets/GameAssets/Resources/Lua/Sample/UISampleForm.lua", "Assets/GameAssets/Resources/Lua/Sample/UISampleForm.lua", "Assets/GameAssets/Resources/Lua/Sample/UISampleForm.lua", }; public string[] FormTempNames = new string[]{ "UITemplate", "UINullTemplate", "UIDialogTemplate" }; //lua脚本名 public string[] FormLuaTempNames = new string[]{ "UISampleForm", "UISampleForm", "UISampleForm" }; private string _formName = "UITestForm"; private string _title = ""; private bool _addScript = false; private bool _addToUIRoot = false; private Assembly _assembly; private DateTime _old; private int _selectTempIndex = 0; void OnGUI() { Horizontal(); GUILayout.Label("窗体名字:", GUILayout.MaxWidth(60)); _formName = EditorGUILayout.TextField(_formName, GUILayout.MaxWidth(150)); EndHorizontal(); GUILayout.Label("选择模板"); _selectTempIndex = EditorGUILayout.Popup(_selectTempIndex, FormTempNames); GUILayout.Label("模板路径"); GUILayout.Label(FORM_TEMPLATE_PREFABS[_selectTempIndex]); Horizontal(); GUILayout.Label("标题:", GUILayout.MaxWidth(60)); _title = EditorGUILayout.TextField(_title, GUILayout.MaxWidth(100)); if (GUILayout.Button("创建CS")) { createForm(); } if (GUILayout.Button("创建Lua")) { createForm(true); } if (GUILayout.Button("添加脚本")) { string savePath = string.Format(FORM_ROOT_PATH, _formName, _formName); addScript(savePath, _formName, _selectTempIndex); } EndHorizontal(); } void OnEnable() { if (_addScript) { string savePath = string.Format(FORM_ROOT_PATH, _formName, _formName); addScript(savePath, _formName, _selectTempIndex); } } void Update() { } void Horizontal() { GUILayout.BeginHorizontal(); } void EndHorizontal() { GUILayout.EndHorizontal(); } private void createForm(bool isLua = false) { UnityEngine.Debug.Log("createForm------"); if (string.IsNullOrEmpty(_formName)) { Debug.LogError("请输入窗体名字"); return; } GameObject uiroot = GameObject.Find("UIRoot"); if (uiroot == null) { uiroot = AssetDatabase.LoadAssetAtPath("Assets/GameAssets/Resources/Default/System/UIRoot.prefab", typeof(GameObject)) as GameObject; uiroot = PrefabUtility.InstantiatePrefab(uiroot) as GameObject; } string savePath = string.Format(FORM_ROOT_PATH, _formName, _formName); Transform formTrans = uiroot.transform.Find(_formName); if (formTrans == null) { createPrefab(savePath, _selectTempIndex, isLua); if (File.Exists(savePath)) { GameObject savedGO = AssetDatabase.LoadAssetAtPath(savePath, typeof(GameObject)) as GameObject; var titleTrans = savedGO.transform.Find("Top/TitleBG/TitleLabel"); if(titleTrans != null) { UILabel titleLabel = titleTrans.GetComponent(); titleLabel.text = string.IsNullOrEmpty(_title) ? titleLabel.text : _title; AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } savedGO = PrefabUtility.InstantiatePrefab(savedGO) as GameObject; savedGO.transform.parent = uiroot.transform; savedGO.transform.localPosition = Vector3.zero; savedGO.transform.localScale = Vector3.one; savedGO.transform.localRotation = Quaternion.identity; Selection.activeGameObject = savedGO; } else { UnityEngine.Debug.LogError("Create prefab fail: " + savePath); } } else { var titleTrans = formTrans.Find("Top/TitleBG/TitleLabel"); if (titleTrans != null) { UILabel titleLabel = titleTrans.GetComponent(); titleLabel.text = string.IsNullOrEmpty(_title) ? titleLabel.text : _title; AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); //这里再改原始prefab GameObject savedGO = AssetDatabase.LoadAssetAtPath(savePath, typeof(GameObject)) as GameObject; var trans = savedGO.transform.Find("Template/TitleHeadBG/TitleLabel"); if(trans != null) { titleLabel = trans.GetComponent(); titleLabel.text = string.IsNullOrEmpty(_title) ? titleLabel.text : _title; AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } } UnityEngine.Debug.Log("createForm------"); } private void createPrefab(string path, int tempIndex, bool isLua = false) { if (!File.Exists(path)) { string saveDir = path.Substring(0, path.LastIndexOf('/')); if (!Directory.Exists(saveDir)) { Directory.CreateDirectory(saveDir); } //var go = AssetDatabase.LoadAssetAtPath(FORM_TEMPLATE_PREFABS[tempIndex], typeof(GameObject)) as GameObject; var go = PrefabUtility.LoadPrefabContents(FORM_TEMPLATE_PREFABS[tempIndex]); PrefabUtility.SaveAsPrefabAsset(go, path); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } addScript(path, _formName, tempIndex, isLua); } private void addScript(string prefabPath, string scriptName, int tempIndex, bool isLua = false) { UnityEngine.Debug.Log("addScript++++++"); //string scriptCopyToPath = string.Format(FORM_SCRIPT_PATH, scriptName, scriptName); string scriptCopyToPath = string.Format(isLua?FORM_LUA_SCRIPT_PATH: FORM_SCRIPT_PATH, scriptName, scriptName); string saveDir = scriptCopyToPath.Substring(0, scriptCopyToPath.LastIndexOf('/')); if (!Directory.Exists(saveDir)) { Directory.CreateDirectory(saveDir); } if (!File.Exists(scriptCopyToPath)) { File.Copy(isLua ? FORM_TEMPLATE_LUA_SCRIPTS[tempIndex] : FORM_TEMPLATE_SCRIPTS[tempIndex], scriptCopyToPath); replaceClassName(scriptCopyToPath, scriptName, isLua); } string prefabSourcePath = prefabPath; UnityEngine.Debug.Log("prefabSourcePath: " + prefabSourcePath); //添加脚本,必须是asset状态,不能实例化,不然加不成功 GameObject assetsGo = AssetDatabase.LoadAssetAtPath(prefabSourcePath, typeof(GameObject)) as GameObject; Type type = getFormType(); if (type == null) { //_addScript = true; UnityEngine.Debug.LogError("~~~~等待unity编译完成后自动添加窗体脚本~~~~"); return; } var script = assetsGo.GetComponent(type); if (script == null) { //UnityEngineInternal.APIUpdaterRuntimeServices.AddComponent(assetsGo, "Assets/Editor/DIY/FormTools/CreateForm.cs (196,17)", scriptName); assetsGo.AddComponent(type); EditorUtility.SetDirty(assetsGo); PrefabUtility.RecordPrefabInstancePropertyModifications(assetsGo); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); UnityEngine.Debug.LogError("添加窗体脚本结束:" + _formName); } _addScript = false; UnityEngine.Debug.Log("addScript------"); } private void replaceClassName(string scriptPath, string scriptName, bool isLua = false) { UnityEngine.Debug.Log("replaceClassName++++++"); if (!File.Exists(scriptPath)) { return; } string codeContent = File.ReadAllText(scriptPath); codeContent = codeContent.Replace(isLua? FormLuaTempNames[_selectTempIndex] : FormTempNames[_selectTempIndex], scriptName); if (!string.IsNullOrEmpty(_title)) codeContent = codeContent.Replace("{请在这里把当前窗体的功能描述写好!}", _title); if (isLua) codeContent = codeContent.Replace("2019-01-01 00:00:00", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); UTF8Encoding coding = new System.Text.UTF8Encoding(false); File.WriteAllText(scriptPath, codeContent, coding); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); AssetDatabase.SaveAssets(); UnityEngine.Debug.Log("replaceClassName--------"); } private Assembly getMainAssembly() { if (_assembly == null) { var asArray = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < asArray.Length; ++i) { if (asArray[i].FullName.IndexOf("Assembly-CSharp,") >= 0) { _assembly = asArray[i]; break; } } } return _assembly; } private Type getFormType() { Type t = null; Assembly assembly = getMainAssembly(); string classPath = "Thousandto.GameUI.Form." + _formName; if (assembly != null) { t = assembly.GetType(classPath); } if (t == null) { UnityEngine.Debug.LogWarning("getFormType null: " + classPath); } return t; } } }