using System.Collections.Generic; using System.IO; using System.Text; using UnityEditor; using UnityEngine; namespace Thousandto.DIY { /// /// 修改窗体脚本,比如添加组件、查找组件、给组件添加事件等 /// public class ModifyFormScript { //总的内容 private List> _contentList; //ui控件列表,对应 #region //UI控件 private List _uiComponentList; //ui查找列表,对应 private void findUIs() private List _uiFindList; //ui事件注册列表,对应 private void registerUIEvent() private List _uiEventList; //ui事件回调函数体, 对应#region //界面按钮回调 private List _uiFuncList; //窗体打开和关闭事件、逻辑事件,对应protected override void OnRegisterEvents() private List _onEventList; //当前脚本路径 private string _curScript; //是否需要保存 private bool _needSave = false; //当前开始字段的index(Lua代码用); private int _index = -1; //当前开始字段(Lua代码用); private List _beginStrList = new List() { "Form = {", "Form:FindAllComponents()", "Form:RegUICallback()", "--[界面按钮回调 begin]--", "Form:OnRegisterEvents()", }; //当前结束字段(Lua代码用); private List _endStrList = new List() { "}", "end", "end", "---[界面按钮回调 end]---", "end", }; private static ModifyFormScript _instance; public static ModifyFormScript Instance { get { if (_instance == null) { _instance = new ModifyFormScript(); } return _instance; } } public ModifyFormScript() { initialize(); } private void initialize() { _contentList = new List>(); _uiComponentList = new List(); _uiFindList = new List(); _uiEventList = new List(); _uiFuncList = new List(); _onEventList = new List(); _curScript = null; _needSave = false; } /// /// 添加组件到脚本中,成员、findUI /// UISprite、UIWidget、UILabel、UIInput、UIScrollView、UIProgressBar、UIGrid、UIToggle。。。 /// /// public void AddUIComponentToScript(Component component) { string formName = ""; string cpPath = ""; findRootAndPath(component, out formName, out cpPath); string scriptPath = ""; bool isLua = false; if (!IsExistScript(formName, out scriptPath, out isLua)) return; parse(scriptPath, isLua); string uiMember = "", findUIStr = "", uiEventStr = "", uiFuncStr = ""; getCpTypeNameAndFinduiStr(component, cpPath, out uiMember, out findUIStr, out uiEventStr, out uiFuncStr, isLua, formName); _needSave = AddToList(_uiComponentList, uiMember); _needSave |= AddToList(_uiFindList, findUIStr); _needSave |= AddToList(_uiEventList, uiEventStr); if (isLua) { _needSave |= AddToList(_uiFuncList, uiFuncStr); } else { _needSave |= AddToList(_uiFuncList, uiFuncStr, true); } if (_needSave) UnityEngine.Debug.LogError("添加成功,需要点击保存按钮才能保存"); else UnityEngine.Debug.LogError("已经添加过了"); } /// /// 自定义组件的检视面板,添加3个按钮 /// UISprite、UIWidget、UILabel、UIInput、UIScrollView、UIProgressBar、UIGrid、UIToggle。。。 /// /// public void CustomComponentInspector(Component target) { if (NGUIEditorTools.DrawHeader("自定义")) { if (!Application.isPlaying) { GUILayout.BeginHorizontal(); if (target.transform.parent != null && target.transform.parent.name != "UIRoot") { if (GUILayout.Button("添加到OnFirstShow", GUILayout.MaxHeight(50), GUILayout.MaxWidth(150))) { AddUIComponentToScript(target); } } if (GUILayout.Button("保存脚本修改", GUILayout.MaxHeight(50), GUILayout.MaxWidth(150))) { SaveScript(target); AddFormToExcel(target); } GUILayout.EndHorizontal(); } GUILayout.Space(5); GUILayout.BeginHorizontal(); GUILayout.Label("节点路径:", GUILayout.MaxWidth(55)); string form = ""; string path = ""; findRootAndPath(target, out form, out path); EditorGUILayout.TextField(path); GUILayout.EndHorizontal(); GUILayout.Space(5); } } /// /// 保存修改到脚本 /// public void SaveScript(Component cp) { string formName = ""; string cpPath = ""; findRootAndPath(cp, out formName, out cpPath); string scriptPath = ""; bool isLua = false; if (!IsExistScript(formName, out scriptPath, out isLua)) return; parse(scriptPath, isLua); if (_contentList == null || _contentList.Count == 0 || !File.Exists(_curScript)) { return; } if (isLua) { _needSave |= AddToList(_onEventList, string.Format("\tself:RegisterEvent(UIEventDefine.{0}_OPEN, self.OnOpen);", formName)); _needSave |= AddToList(_onEventList, string.Format("\tself:RegisterEvent(UIEventDefine.{0}_CLOSE, self.OnClose);", formName)); } else { _needSave |= AddToList(_onEventList, string.Format(" RegisterEvent((int)UIEventDefine.{0}_OPEN, OnOpen);", formName)); _needSave |= AddToList(_onEventList, string.Format(" RegisterEvent((int)UIEventDefine.{0}_CLOSE, OnClose);", formName)); } if (!_needSave) { UnityEngine.Debug.LogError("不需要保存"); return; } StreamWriter sw = new StreamWriter(_curScript); for (int i = 0; i < _contentList.Count; ++i) { for (int m = 0; m < _contentList[i].Count; ++m) { sw.WriteLine(_contentList[i][m]); } } sw.Close(); Debug.LogError("保存脚本成功"); initialize(); } /// /// 将窗体添加到UIConfig.xlsx表中 /// /// public void AddFormToExcel(Component target) { SvnOption.UpdateFile(Path.GetFullPath(UIConfigExcel.ExcelPath)); string form = ""; string path = ""; findRootAndPath(target, out form, out path); int formId = -1; string scriptPath = ""; bool isLua = false; IsExistScript(form,out scriptPath, out isLua); if (UIConfigExcel.AddForm(form, out formId, isLua)) { SvnOption.CommitFile(Path.GetFullPath(UIConfigExcel.ExcelPath)); if (formId > 0) { SvnOption.UpdateFile(Path.GetFullPath(ModifyUIEventDefine.UIEVENT_FILE_PATH)); ModifyUIEventDefine.ModifyFile(form, formId); SvnOption.CommitFile(Path.GetFullPath(ModifyUIEventDefine.UIEVENT_FILE_PATH)); } } } /// /// 获取组件名字作为成员变量 /// 获取findChild的字符串 /// /// 需要添加到脚本中的组件实例 /// 组件的层次路径,用于findchild /// 组件在脚本中的成员变量 /// 返回的FindChild字符串 /// 返回拼接好的事件注册字符串 /// 返回拼接的事件回调函数 private void getCpTypeNameAndFinduiStr(Component component, string cpPath, out string uiMember, out string findStr, out string eventStr, out string funcStr, bool isLua, string formName) { string classStr = component.GetType().Name; string sourceName = FirstCharToHigh(component.gameObject.name); string goName = isLua ? sourceName : string.Format("_{0}", FirstCharToLow(sourceName)); eventStr = ""; funcStr = ""; if (component is UISprite) { if (component.transform.GetComponent() != null) { if (isLua) { uiMember = string.Format("\t{0} = nil,", goName); classStr = "Btn"; eventStr = string.Format("\tUIUtils.AddBtnEvent(self.{0}, self.OnClick{1}CallBack, self);", goName, sourceName); funcStr = string.Format("function {0}:OnClick{1}CallBack()\nend", formName, sourceName); } else { uiMember = string.Format(" private {0} {1};", "UIButton", goName); classStr = "UIButton"; eventStr = string.Format(" {0}.onClick.Clear();EventDelegate.Add({1}.onClick, OnClick{2});", goName, goName, sourceName); funcStr = string.Format(" private void OnClick{0}(){{}}", sourceName); } } else { if (isLua) { uiMember = string.Format("\t{0} = nil,", goName); classStr = "Spr"; } else uiMember = string.Format(" private {0} {1};", "UISprite", goName); } } else { if (isLua) uiMember = string.Format("\t{0} = nil,", goName); else uiMember = string.Format(" private {0} {1};", classStr, goName); } if (isLua) { if (classStr == "UITexture") { classStr = "Tex"; } else if (classStr == "UILabel") { classStr = "Label"; } else if (classStr == "UIPanel") { classStr = "Panel"; } else if (classStr == "UIWidget") { classStr = "Wid"; } else if (classStr == "UIGrid") { classStr = "Grid"; } else if (classStr == "UITable") { classStr = "Table"; } else if (classStr == "UIToggle") { classStr = "Toggle"; } findStr = string.Format("\tself.{0} = UIUtils.Find{1}(_myTrans, \"{2}\");", goName, classStr, cpPath); } else findStr = string.Format(" {0} = TransformInst.Find(\"{1}\").GetComponent<{2}>();", goName, cpPath, classStr); } /// /// 是否包含 /// /// /// /// private bool contains(List list, string name) { for (int i = 0; list != null && i < list.Count; ++i) { if (list[i].IndexOf(name) >= 0) { return true; } } return false; } /// /// 将生成的字符串添加到对应的列表中 /// /// /// /// /// private bool AddToList(List list, string text, bool isFuncList = false) { if (contains(list, text)) { return false; } if (isFuncList) { list.Add(text); } else { int index = 0; if (list.Count > 0) index = list.Count - 1; list.Insert(index, text); } return true; } /// /// 查找节点的根节点和节点的层次路径 /// /// /// /// private void findRootAndPath(Component cpt, out string formName, out string componentPath) { string name = ""; StringBuilder pathSB = new StringBuilder(); Component temp = cpt; Component parent = null; while ((parent = temp.transform.parent) != null) { if (parent.gameObject.name == "UIRoot") { name = temp.gameObject.name; break; } string cpPath = "/" + temp.gameObject.name; pathSB.Insert(0, cpPath); temp = parent; } if (string.IsNullOrEmpty(name)) { name = temp.gameObject.name; } formName = name; componentPath = pathSB.ToString().TrimStart('/'); } private void parse(string scriptPath, bool isLua) { if ((!string.IsNullOrEmpty(_curScript) && scriptPath != _curScript)) { UnityEngine.Debug.LogError("切换了窗体,重新初始化: " + scriptPath); initialize(); } if (_contentList != null && _contentList.Count != 0) { return; } _curScript = scriptPath; StreamReader sr = new StreamReader(scriptPath); string line = null; //特殊的几个list List curList = null; //普通list List commonList = null; //函数体,计数大括号 int funcSign = 0; bool hasFunc = false; while ((line = sr.ReadLine()) != null) { if (curList == null) { curList = getMemberList(line, isLua); if (curList != null) { commonList = null; _contentList.Add(curList); } } if (curList != null) { curList.Add(line); if (isLua) { if (_endStrList[_index] == "end") { if(line.IndexOf("function ") >= 0|| line.IndexOf("for ") >= 0|| line.IndexOf("while ") >= 0|| line.IndexOf("if ") >= 0) { funcSign++; } else if (line.IndexOf("end") >= 0) { funcSign--; } if(funcSign == 0) { _index = -1; curList = null; hasFunc = false; funcSign = 0; } } else if(line.IndexOf(_endStrList[_index])>= 0) { _index = -1; curList = null; } } else { if (line.IndexOf("#endregion") >= 0) { curList = null; } if (line.IndexOf("{") >= 0) { funcSign++; hasFunc = true; } if (line.IndexOf("}") >= 0) { funcSign--; } if (hasFunc && funcSign == 0) { curList = null; hasFunc = false; funcSign = 0; } } continue; } if (commonList == null) { commonList = new List(); _contentList.Add(commonList); } if (commonList != null) { commonList.Add(line); } } sr.Close(); } private List getMemberList(string line, bool isLua) { List retList = null; if (isLua) { if (line.IndexOf(_beginStrList[0]) >= 0) { _index = 0; retList = _uiComponentList; } else if (line.IndexOf(_beginStrList[1]) >= 0) { _index = 1; retList = _uiFindList; } else if (line.IndexOf(_beginStrList[2]) >= 0) { _index = 2; retList = _uiEventList; } else if (line.IndexOf(_beginStrList[3]) >= 0) { _index = 3; retList = _uiFuncList; } else if (line.IndexOf(_beginStrList[4]) >= 0) { _index = 4; retList = _onEventList; } } else { if (line.IndexOf("#region //UI控件") >= 0) { retList = _uiComponentList; } else if (line.IndexOf("private void FindAllComponents()") >= 0) { retList = _uiFindList; } else if (line.IndexOf("private void RegUICallback()") >= 0) { retList = _uiEventList; } else if (line.IndexOf("#region //界面按钮回调") >= 0) { retList = _uiFuncList; } else if (line.IndexOf("protected override void OnRegisterEvents()") >= 0) { retList = _onEventList; } } return retList; } private string FirstCharToLow(string str) { if (string.IsNullOrEmpty(str)) return str; char[] chars = str.ToCharArray(); if (chars[0] >= 65 && chars[0] <= 90) chars[0] = (char)(chars[0] + 32); return new string(chars); } private string FirstCharToHigh(string str) { if (string.IsNullOrEmpty(str)) return str; char[] chars = str.ToCharArray(); if (chars[0] >= 97 && chars[0] <= 122) chars[0] = (char)(chars[0] - 32); return new string(chars); } //脚本是否存在 private bool IsExistScript(string formName, out string scriptPath, out bool isLua) { scriptPath = string.Format(CreateForm.FORM_SCRIPT_PATH, formName, formName); if (File.Exists(scriptPath)) { isLua = false; return true; } scriptPath = string.Format(CreateForm.FORM_LUA_SCRIPT_PATH, formName, formName); if (File.Exists(scriptPath)) { isLua = true; return true; } UnityEngine.Debug.LogError("脚本不存在,请先创建脚本: " + formName); scriptPath = ""; isLua = false; return false; } } }