630 lines
21 KiB
C#
630 lines
21 KiB
C#
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Text;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
|
||
namespace Thousandto.DIY
|
||
{
|
||
/// <summary>
|
||
/// 修改窗体脚本,比如添加组件、查找组件、给组件添加事件等
|
||
/// </summary>
|
||
public class ModifyFormScript
|
||
{
|
||
//总的内容
|
||
private List<List<string>> _contentList;
|
||
|
||
//ui控件列表,对应 #region //UI控件
|
||
private List<string> _uiComponentList;
|
||
//ui查找列表,对应 private void findUIs()
|
||
private List<string> _uiFindList;
|
||
//ui事件注册列表,对应 private void registerUIEvent()
|
||
private List<string> _uiEventList;
|
||
//ui事件回调函数体, 对应#region //界面按钮回调
|
||
private List<string> _uiFuncList;
|
||
//窗体打开和关闭事件、逻辑事件,对应protected override void OnRegisterEvents()
|
||
private List<string> _onEventList;
|
||
|
||
//当前脚本路径
|
||
private string _curScript;
|
||
//是否需要保存
|
||
private bool _needSave = false;
|
||
|
||
//当前开始字段的index(Lua代码用);
|
||
private int _index = -1;
|
||
//当前开始字段(Lua代码用);
|
||
private List<string> _beginStrList = new List<string>() {
|
||
"Form = {",
|
||
"Form:FindAllComponents()",
|
||
"Form:RegUICallback()",
|
||
"--[界面按钮回调 begin]--",
|
||
"Form:OnRegisterEvents()",
|
||
};
|
||
//当前结束字段(Lua代码用);
|
||
private List<string> _endStrList = new List<string>() {
|
||
"}",
|
||
"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<List<string>>();
|
||
_uiComponentList = new List<string>();
|
||
_uiFindList = new List<string>();
|
||
_uiEventList = new List<string>();
|
||
_uiFuncList = new List<string>();
|
||
_onEventList = new List<string>();
|
||
_curScript = null;
|
||
_needSave = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加组件到脚本中,成员、findUI
|
||
/// UISprite、UIWidget、UILabel、UIInput、UIScrollView、UIProgressBar、UIGrid、UIToggle。。。
|
||
/// </summary>
|
||
/// <param name="component"></param>
|
||
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("已经添加过了");
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 自定义组件的检视面板,添加3个按钮
|
||
/// UISprite、UIWidget、UILabel、UIInput、UIScrollView、UIProgressBar、UIGrid、UIToggle。。。
|
||
/// </summary>
|
||
/// <param name="target"></param>
|
||
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);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 保存修改到脚本
|
||
/// </summary>
|
||
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();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将窗体添加到UIConfig.xlsx表中
|
||
/// </summary>
|
||
/// <param name="target"></param>
|
||
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));
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取组件名字作为成员变量
|
||
/// 获取findChild的字符串
|
||
/// </summary>
|
||
/// <param name="component">需要添加到脚本中的组件实例</param>
|
||
/// <param name="cpPath">组件的层次路径,用于findchild</param>
|
||
/// <param name="uiMember">组件在脚本中的成员变量</param>
|
||
/// <param name="findStr">返回的FindChild字符串</param>
|
||
/// <param name="eventStr">返回拼接好的事件注册字符串</param>
|
||
/// <param name="funcStr">返回拼接的事件回调函数</param>
|
||
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<UIButton>() != 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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 是否包含
|
||
/// </summary>
|
||
/// <param name="list"></param>
|
||
/// <param name="name"></param>
|
||
/// <returns></returns>
|
||
private bool contains(List<string> list, string name)
|
||
{
|
||
for (int i = 0; list != null && i < list.Count; ++i)
|
||
{
|
||
if (list[i].IndexOf(name) >= 0)
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将生成的字符串添加到对应的列表中
|
||
/// </summary>
|
||
/// <param name="list"></param>
|
||
/// <param name="text"></param>
|
||
/// <param name="isFuncList"></param>
|
||
/// <returns></returns>
|
||
private bool AddToList(List<string> 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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 查找节点的根节点和节点的层次路径
|
||
/// </summary>
|
||
/// <param name="cpt"></param>
|
||
/// <param name="formName"></param>
|
||
/// <param name="componentPath"></param>
|
||
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<string> curList = null;
|
||
//普通list
|
||
List<string> 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<string>();
|
||
_contentList.Add(commonList);
|
||
}
|
||
|
||
if (commonList != null)
|
||
{
|
||
commonList.Add(line);
|
||
}
|
||
}
|
||
|
||
sr.Close();
|
||
}
|
||
|
||
|
||
private List<string> getMemberList(string line, bool isLua)
|
||
{
|
||
List<string> 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;
|
||
}
|
||
}
|
||
}
|