public UIExportData[] ExportData = null; //所有要导出的数据 /// <summary> /// 遍历指定物体节点下的所有UIProgramData,然后根据回调进行引用赋值 /// </summary> /// <param name="thisObjRoot">物体根节点</param> /// <param name="handle">赋值回调</param> public static void ForEachDataByCode(GameObject thisObjRoot, SetUIProgramDataCompReference handle) { if (handle == null || thisObjRoot == null) { return; } UIProgramData[] allData = thisObjRoot.GetComponentsInChildren <UIProgramData>(true); if (null == allData || allData.Length == 0) { return; } for (int iLoop = 0; iLoop < allData.Length; iLoop++) { UIProgramData programData = allData[iLoop]; if (null != programData.ExportData && programData.ExportData.Length > 0) { for (int iIndex = 0; iIndex < programData.ExportData.Length; iIndex++) { UIExportData exportData = programData.ExportData[iIndex]; handle(programData, exportData); } } } }
/// <summary> /// 检测变量数据是否合法 /// </summary> private void CheckVariableData(UIProgramData pData) { for (int i = 0; i < pData.ExportData.Length; i++) { UIExportData data = pData.ExportData[i]; if (data == null) { continue; } //检测数据 if (data.isArrayData) { //检测数组是否为Null或者数组内有Null bool isErrorData = false; if (data.CompReferenceArray == null) { isErrorData = true; } else { foreach (var item in data.CompReferenceArray) { if (item == null) { isErrorData = true; break; } } } if (isErrorData) { throw new UIExportDataException(string.Format("Variable data error.It is array data,but array is null or element is null. Variable name is {0} !", data.VariableName), pData); } } else { //非数组,检测引用是否为Null if (data.CompReference == null) { throw new UIExportDataException(string.Format("Variable data error.It is null. Variable name is {0} !", data.VariableName), pData); } } //检测变量名 if (!CheckVariableOrClassName(data.VariableName)) { throw new UIExportDataException(string.Format("Variable name error.It is null or has blank space and variable name is {0} !", data.VariableName), pData); } } }
/// <summary> /// 获取变量的简称类型 /// </summary> private string GetVariableType(UIExportData data) { string type = ""; if (data.CompReference == null) { type = "GameObject"; } else { type = data.CompReference.GetType().Name; } return(type); }
private static void SetFieldValue(object uiData, System.Reflection.FieldInfo field, UIDataAttribute dataAtt) { for (int x = 0, xMax = dataList.Count; x < xMax; x++) { UIExportData exportData = dataList[x]; if (exportData != null && exportData.VariableName.Equals(dataAtt.FieldName)) { if (exportData.isArrayData) { System.Array dataArr = null; if (exportData.isGameObjectRef) { dataArr = System.Array.CreateInstance(typeof(GameObject), exportData.CompReferenceArray.Length); } else { dataArr = System.Array.CreateInstance(exportData.CompReferenceArray[0].GetType(), exportData.CompReferenceArray.Length); } for (int y = 0; y < exportData.CompReferenceArray.Length; y++) { if (exportData.isGameObjectRef) { dataArr.SetValue(exportData.CompReferenceArray[y].gameObject, y); } else { dataArr.SetValue(exportData.CompReferenceArray[y], y); } } field.SetValue(uiData, dataArr); } else { if (exportData.isGameObjectRef) { field.SetValue(uiData, exportData.CompReference.gameObject); } else { field.SetValue(uiData, exportData.CompReference); } } dataList[x] = null; break; } } }
/// <summary> /// 遍历指定物体节点下的所有UIProgramData,然后根据字段名反射赋值 /// </summary> /// <param name="rootObj">物体根节点</param> /// <param name="uiData">UIData对象</param> public static void ForEachDataByAttribute(GameObject rootObj, object uiData) { dataList.Clear(); if (rootObj == null || uiData == null) { return; } UIProgramData[] allData = rootObj.GetComponentsInChildren <UIProgramData>(true); if (null == allData || allData.Length == 0) { return; } for (int iLoop = 0; iLoop < allData.Length; iLoop++) { UIProgramData programData = allData[iLoop]; if (null != programData.ExportData && programData.ExportData.Length > 0) { for (int iIndex = 0; iIndex < programData.ExportData.Length; iIndex++) { UIExportData exportData = programData.ExportData[iIndex]; dataList.Add(exportData); } } } System.Reflection.FieldInfo[] fieldInfoArr = uiData.GetType().GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public); foreach (var field in fieldInfoArr) { object[] objAtts = field.GetCustomAttributes(typeof(UIDataAttribute), false); if (objAtts != null && objAtts.Length > 0) { for (int j = 0, jMax = objAtts.Length; j < jMax; j++) { if (objAtts[j] == null) { continue; } UIDataAttribute dataAtt = objAtts[j] as UIDataAttribute; SetFieldValue(uiData, field, dataAtt); } } } }
/// <summary> /// 将UIProgramData中的变量添加到数组中 /// </summary> private void AddContainerToVariablesList(string key, UIProgramData pData, UIProgramData[] ProgramDatas, Dictionary <string, List <UIExportData> > dic_ClassAndVariables) { //1:检测变量数据是否合法 CheckVariableData(pData); if (dic_ClassAndVariables.ContainsKey(key)) { List <UIExportData> dataList = dic_ClassAndVariables[key]; foreach (var data in pData.ExportData) { UIExportData sameData = dataList.Find(d => d.VariableName.Equals(data.VariableName)); if (sameData != null) { //证明已存在相同变量名,那就找出这个物体,抛异常 UIProgramData hasObj = null; foreach (var item in ProgramDatas) { if (item == pData) { continue; } foreach (var exportData in item.ExportData) { if (exportData == sameData) { hasObj = item; goto throwLine; } } } throwLine: throw new UIExportDataException(string.Format("The variables has same and variable name is {0} !", data.VariableName), pData, hasObj); } dataList.Add(data); } } else { throw new UIExportDataException(string.Format("Don't has this class and class name is {0}", key), pData); } }
/// <summary> /// 生成一个变量(变量标识名,变量字段,变量属性) /// </summary> private void WriteVariable(UIExportData data, string className) { string type = GetVariableType(data); string constStrVaiableName = JointString("_", data.VariableName, "_Name"); string privateVariableName = JointString("_", data.VariableName); classWriter.WriteLine(); classWriter.WriteLine("#region ", type, " ", data.VariableName); //物体的引用变量名 classWriter.WriteLine("private const string ", constStrVaiableName, " = \"", data.VariableName, "\";"); //物体的引用 classWriter.WriteLine("private ", type, " ", privateVariableName, ";"); //物体的Get属性 classWriter.WriteLine("public ", type, " ", data.VariableName); classWriter.WriteBraceLeft(); { classWriter.WriteLine("get"); classWriter.WriteBraceLeft(); { classWriter.WriteLine("if (null == ", privateVariableName, ")"); if (data.CompReference == null) { //证明是GameObject classWriter.WriteLine(1, privateVariableName, " = DefaultObjForUI.DefaultGameObject(this, \"ClassName_", className, " VariableName_", data.VariableName, "\");"); } else { //证明是组件 classWriter.WriteLine(1, privateVariableName, " = DefaultObjForUI.DefaultComponent<", type, ">(this, \"ClassName_", className, " VariableName_", data.VariableName, "\");"); } classWriter.WriteLine("return ", privateVariableName, ";"); } classWriter.WriteLineBraceRight(); } classWriter.WriteLineBraceRight(); classWriter.WriteLine("#endregion"); }
/// <summary> /// 生成单个类模块 /// </summary> private void CreateClass(string className, List <UIExportData> datas) { classWriter.WriteLine("public partial class ", className); classWriter.WriteBraceLeft(); #region 变量区 classWriter.WriteLine("public GameObject thisObjRoot;"); for (int i = 0; i < datas.Count; i++) { UIExportData data = datas[i]; WriteVariable(data, className); } #endregion classWriter.WriteLine(); #region 析构函数区 classWriter.WriteLine("~", className, "()"); classWriter.WriteBraceLeft(); classWriter.WriteLine("Clear();"); classWriter.WriteLineBraceRight(); #endregion classWriter.WriteLine(); #region Init方法区 classWriter.WriteLine("public void Init(GameObject objRoot)"); classWriter.WriteBraceLeft();//Start of init function { classWriter.WriteLine("if (objRoot == null)"); classWriter.WriteLine(1, "return;"); classWriter.WriteLine(); classWriter.WriteLine("thisObjRoot = objRoot;"); classWriter.WriteLine("thisObjRoot.SetActive(true);"); classWriter.WriteLine(); classWriter.WriteLine("UIProgramData[] allData = thisObjRoot.GetComponentsInChildren<UIProgramData>(true);"); classWriter.WriteLine("if (null == allData || allData.Length <= 0)"); classWriter.WriteLine(1, "return;"); classWriter.WriteLine(); #region 遍历UIProgramData,并为当前脚本的引用赋值 classWriter.WriteLine("for (int iLoop = 0; iLoop < allData.Length; iLoop++)"); classWriter.WriteBraceLeft();//Start of for UIProgramData { classWriter.WriteLine("UIProgramData programData = allData[iLoop];"); classWriter.WriteLine("if (null != programData.ExportData && programData.ExportData.Length > 0)"); classWriter.WriteBraceLeft();//Start of if programData.ExportData { #region 遍历UIExportData classWriter.WriteLine("for (int iIndex = 0; iIndex < programData.ExportData.Length; iIndex++)"); classWriter.WriteBraceLeft(); { classWriter.WriteLine("UIExportData exportData = programData.ExportData[iIndex];"); classWriter.WriteLine("switch (exportData.VariableName)"); classWriter.WriteBraceLeft(); { for (int i = 0; i < datas.Count; i++) { UIExportData data = datas[i]; classWriter.WriteLine("case ", "_", data.VariableName, "_Name", ":"); classWriter.WriteLine(1, "_", data.VariableName, " = ", (data.CompReference == null ? "programData.gameObject;" : JointString("(", data.CompReference.GetType().Name, ")", "exportData.CompReference;"))); classWriter.WriteLine(1, "break;"); } } classWriter.WriteLineBraceRight(); } classWriter.WriteLineBraceRight(); #endregion } classWriter.WriteLineBraceRight(); //End of if programData.ExportData } classWriter.WriteLineBraceRight(); //End of for UIProgramData #endregion } classWriter.WriteLineBraceRight();//End of function #endregion classWriter.WriteLine(); #region Clear方法区 classWriter.WriteLine("public void Clear()"); classWriter.WriteBraceLeft();//Start of clear function { //置空Root classWriter.WriteLine("thisObjRoot = null;"); //置空变量 for (int i = 0; i < datas.Count; i++) { UIExportData data = datas[i]; string variableName = JointString("_", data.VariableName); classWriter.WriteLine(variableName + " = null;"); } //删除这个对象创建的GameObject classWriter.WriteLine("DefaultObjForUI.DestroyGameObjectByObjGen(this);"); } classWriter.WriteLineBraceRight();//End of clear function #endregion classWriter.WriteLineBraceRight(); }