上一篇的加强版:NGUI通过XML布局
发布时间:2020-12-16 06:25:35 所属栏目:百科 来源:网络整理
导读:反正做都做了,再做一个用XML来布局并生成界面的 运行前它是这个样子: 运行TestXMLloadUI.cs脚本后,就生成了一个UI: 其中,加载XML布局的代码如下: using UnityEngine;using System.Collections;public class testXMLloadUI : MonoBehaviour {// Use thi
|
反正做都做了,再做一个用XML来布局并生成界面的 运行前它是这个样子:
运行TestXMLloadUI.cs脚本后,就生成了一个UI:
其中,加载XML布局的代码如下: using UnityEngine;
using System.Collections;
public class testXMLloadUI : MonoBehaviour {
// Use this for initialization
void Start () {
UICreator.GetInstance().LoadFromXML(@"E:workcardToolsAssetsXMLFile1.xml");
}
}
XMLFile1.xml的内容如下: <?xml version="1.0" encoding="utf-8" ?>
<NGUILayout xmlns:UIyang ="983323204">
<UIRoot
name ="UI_TEST"
depth ="0"
parentName ="ui_1">
<Sprite
adpClass = "SpriteAdp"
objName ="tSprite"
depth ="2"
atlasName ="xxx"
spriteName = "Emoticon - Frown"
width = "100"
height = "100"
collider = "false"
updateColByCOM = "true"
cX = "10"
cY = "10">
<Layout
alignParentTop=""
alignParentBaseLineX ="">
</Layout>
</Sprite>
<Label
adpClass = "LabelAdp"
objName ="tLabel"
depth ="3"
width ="100"
height ="100"
collider ="false"
text ="xxxx"
updateColByCOM = "true"
cX = "10"
cY = "10">
<Layout
alignParentBottom=""
alignParentBaseLineX="">
</Layout>
</Label>
<Texture
adpClass = "NormalCOMAdp"
objName ="tTexture"
depth ="1"
width ="10"
height ="10"
collider ="false"
updateColByCOM = "true"
cX = "10"
cY = "10">
<Layout
fillParent="">
</Layout>
</Texture>
<MeteDate
adpClass = "MeteDateAdp"
objName ="md"
depth ="4">
<Layout
centerHorizontal=""
centerVertical="">
</Layout>
</MeteDate>
</UIRoot>
</NGUILayout>
格式是我自己定义的,每个组件有它自己的属性和一个布局,其中布局的string是和上一篇中的布局enum一致的,并且在代码中有互相转换的地方 那么,重要部分来了,解析XML并生成UI的代码如下: using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System;
using yang.UI;
using System.Reflection;
public class UICreator : MonoBehaviour {
static UICreator instance;
public static UICreator GetInstance() {
return instance;
}
void Awake() {
instance = this;
}
public UIWidget[] template;
public string LastError;
public UIWidget ui;
public List<UIWidget> LoadFromXML(string url,Func<string,string> fileHandle = null){
string xmlPath;
if(fileHandle!=null){
xmlPath = fileHandle(url);
}else{
xmlPath = url;
}
List<UIWidget> lst_R_N = null;
//try {
XmlTextReader xTR = new XmlTextReader(xmlPath);
xTR.WhitespaceHandling = WhitespaceHandling.None;
while(xTR.Read()){
xTR.MoveToElement();
int nd = xTR.Depth;
if (xTR.NodeType == XmlNodeType.EndElement)
continue;
//Debug.Log("current: " + xTR.Name+",depth:"+nd);
switch (nd) {
case 0://XML声明,不处理
break;
case 1://UIRoot
if (lst_R_N != null)
return null;
else {
//生成实例
GameObject uiroot = Instantiate(ui.gameObject) as GameObject;
UIWidget R = uiroot.GetComponent<UIWidget>();
//获得属性
string uiName = xTR.GetAttribute("name");
string depth = xTR.GetAttribute("depth");
string parentName = xTR.GetAttribute("parentName");
//放入场景
uiroot.name = uiName;
R.depth = Int32.Parse(depth);
UIRect pHook = getUIParent(parentName);
uiroot.transform.parent = pHook.transform;
uiroot.transform.localScale = Vector3.one;
Dictionary<Layout,string> hLayout = new Dictionary<Layout,string>();
hLayout.Add(Layout.fillParent,"");
UILayoutTool.LayoutUI(R,null,hLayout);
lst_R_N = new List<UIWidget>();
lst_R_N.Add(R);
}
break;
case 2://widget
if (lst_R_N == null) {
Debug.Log("return");
return null;
} else {
string nodeName = xTR.Name;
WidgetType wt;
try {
wt = (WidgetType)Enum.Parse(typeof(WidgetType),nodeName);
} catch {
Debug.Log("转换失败:" + nodeName);
wt = WidgetType.None;
}
//生成实例
int index = (int)wt;
GameObject inst = Instantiate(template[index].gameObject) as GameObject;
UIWidget w = inst.GetComponent<UIWidget>();
//获得适配类名并反射执行
string adpClass = xTR.GetAttribute("adpClass");
//Debug.Log(xTR.Name+","+adpClass+",");
Type adp = Type.GetType(adpClass);
var CInfo = adp.GetConstructor(Type.EmptyTypes);
var objAdp = CInfo.Invoke(null);
MethodInfo minfo = adp.GetMethod("Init");
minfo.Invoke(objAdp,new object[] {xTR,w});
//放入场景
GameObject uiroot = lst_R_N[0].gameObject;
inst.transform.parent = uiroot.transform;
inst.transform.localScale = Vector3.one;
lst_R_N.Add(w);
}
break;
case 3://layout
if (lst_R_N == null) {
return null;
} else {
UIWidget currentWidget = lst_R_N[lst_R_N.Count - 1];
Dictionary<Layout,string> layout = new Dictionary<Layout,string>();
int ac = xTR.AttributeCount;
for (int i = 0; i < ac; i++) {
xTR.MoveToAttribute(i);
string k = xTR.Name;
string v = xTR.Value;
layout.Add((Layout)Enum.Parse(typeof(Layout),k),v);
}
UILayoutTool.LayoutUI(currentWidget,layout);
//xTR.MoveToElement();
}
break;
default://其它层节点,不处理
break;
}
}
return lst_R_N;
//} catch (Exception e){
// Debug.Log(e.ToString());
// return null;
//}
}
public UIRect defaultRoot;
/// <summary>
/// 寻找UI挂接点
/// </summary>
private UIRect getUIParent(string name){
return defaultRoot;
}
}
//UI组件
public class COMAdp {
public virtual void Init(XmlTextReader xTR,UIWidget widget) {
string comName = xTR.GetAttribute("objName");
string depth = xTR.GetAttribute("depth");
widget.gameObject.name = comName;
widget.depth = Int32.Parse(depth);
}
}
public class NormalCOMAdp : COMAdp {
public override void Init(XmlTextReader xTR,UIWidget widget) {
base.Init(xTR,widget);
string width = xTR.GetAttribute("width");
string heigth = xTR.GetAttribute("height");
string collider = xTR.GetAttribute("collider");
string updateColByCOM = xTR.GetAttribute("updateColByCOM");
string cX = xTR.GetAttribute("cX");
string cY = xTR.GetAttribute("cY");
widget.width = Int32.Parse(width);
widget.height = Int32.Parse(heigth);
if(Boolean.Parse(collider)){
var col = widget.gameObject.AddComponent<BoxCollider>();
if (Boolean.Parse(updateColByCOM)) {
widget.autoResizeBoxCollider = true;
} else {
col.size = new Vector3(Int32.Parse(cX),Int32.Parse(cY));
}
}
}
}
public class SpriteAdp : NormalCOMAdp {
public override void Init(XmlTextReader xTR,widget);
string atlasName = xTR.GetAttribute("atlasName");
string spriteName = xTR.GetAttribute("spriteName");
var s = (UISprite)widget;
s.spriteName = spriteName;
}
}
public class LabelAdp : NormalCOMAdp {
public override void Init(XmlTextReader xTR,widget);
string text = xTR.GetAttribute("text");
var l = (UILabel)widget;
l.text = text;
}
}
public class MeteDateAdp : COMAdp {
public override void Init(XmlTextReader xTR,widget);
}
}
同时在调试的过程中发现上一篇的UILayoutTool.cs是存在问题的,就是上次是布局已经存在于场景中的UIWidget,而这一次是从prefab生成的,所以72-75行的获取组件父物体方法是失败的,大概原因是prefab的脚本缓存了错误的父物体,改为如下则没有问题了: <span style="white-space:pre"> </span>if (NGUITools.FindInParents<UIRect>(widget.transform.parent.gameObject).GetType() == typeof(UIPanel)) {
ptarget = (UIPanel)NGUITools.FindInParents<UIRect>(widget.transform.parent.gameObject);
} else {
target = (UIWidget)NGUITools.FindInParents<UIRect>(widget.transform.parent.gameObject);
}
写得比较粗糙,目前还存在的问题有: XML的格式要求比较严格,没做缺省参数检查,必须写完所有参数;在XML中也不支持注释等 Sprite没有做加载图集部分,现在只能用prefab指定的图集 Textrue同样没有做设置mainTexture的部分,需要手动在其它地方设置 MeteData类型的UI组件要自己写XML属性提取 不过,LoadFromXML函数返回了UI的根和所有的组件的list,可以利用它做更多的事情,也可以结合一些动态脚本什么的,做更多东西 哦,对了,还有个UICreatorEditor.cs,就是UICreator的面板显示脚本: using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(UICreator),true)]
public class UICreatorEditor : Editor {
protected UICreator mUICreator;
void OnEnable() {
mUICreator = target as UICreator;
if(mUICreator.template == null)
mUICreator.template = new UIWidget[10];
}
public override void OnInspectorGUI() {
//base.OnInspectorGUI();
serializedObject.Update();
mUICreator.defaultRoot = (UIRect)EditorGUILayout.ObjectField("默认UI挂接点",mUICreator.defaultRoot,typeof(UIRect));
mUICreator.ui = (UIWidget)EditorGUILayout.ObjectField("UI根",mUICreator.ui,typeof(UIWidget));
EditorGUILayout.Separator();
if (NGUIEditorTools.DrawHeader("prefab")) {
NGUIEditorTools.BeginContents();
mUICreator.template[0] = (UIWidget)EditorGUILayout.ObjectField("MeteDate(自定义)",mUICreator.template[0],typeof(UIWidget));
mUICreator.template[1] = (UIWidget)EditorGUILayout.ObjectField("Sprite(精灵)",mUICreator.template[1],typeof(UIWidget));
mUICreator.template[2] = (UIWidget)EditorGUILayout.ObjectField("Label(字符串)",mUICreator.template[2],typeof(UIWidget));
mUICreator.template[3] = (UIWidget)EditorGUILayout.ObjectField("Texture(纹理)",mUICreator.template[3],typeof(UIWidget));
mUICreator.template[4] = (UIWidget)EditorGUILayout.ObjectField("Button(按钮)",mUICreator.template[4],typeof(UIWidget));
mUICreator.template[5] = (UIWidget)EditorGUILayout.ObjectField("Toggle(选择框)",mUICreator.template[5],typeof(UIWidget));
mUICreator.template[6] = (UIWidget)EditorGUILayout.ObjectField("ProgressBar(进度条)",mUICreator.template[6],typeof(UIWidget));
mUICreator.template[7] = (UIWidget)EditorGUILayout.ObjectField("Slider(滑动条)",mUICreator.template[7],typeof(UIWidget));
mUICreator.template[8] = (UIWidget)EditorGUILayout.ObjectField("Input(输入框)",mUICreator.template[8],typeof(UIWidget));
mUICreator.template[9] = (UIWidget)EditorGUILayout.ObjectField("ScrollBar(滚动条)",mUICreator.template[9],typeof(UIWidget));
NGUIEditorTools.EndContents();
}
EditorGUILayout.Separator();
serializedObject.ApplyModifiedProperties();
}
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
- The Swift Programming Language swift 4 下载地
- c# – IoC未在Win7 / XP上初始化
- flex – Flash Builder与FlashDevelop的优点/缺点
- 如何在Ajax请求之后重新生成jQuery Mobile样式?
- ruby-on-rails – rails,action mailer不发送
- ruby-on-rails – 设计从gem而不是生成的视图渲染
- 正则表达式 – 将一列拆分为多个列,R中没有明确的
- flash as3的文字描边效果和投影效果
- oracle 发送邮件 实现方法
- cocos js- android 平台 java与js互调 , ios平台
热点阅读
