unity3d场景导出XML或JSON并且解析还原场景
前端之家收集整理的这篇文章主要介绍了
unity3d场景导出XML或JSON并且解析还原场景,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
导出
unity
场景的所有游戏对象信息,一种是XML一种是JSON。本篇文章我们把游戏场景中游戏对象的、旋转、缩放、平移与Prefab的名称导出在XML与JSON中。然后解析刚刚导出的XML或JSON通过脚本把导出的游戏场景还原。在Unity官网上下载随便下载一个demo Project,如下图所示这是我刚刚在官网上下载的一个范例程序。
接着将层次视图中的所有游戏对象都封装成Prefab保存在资源路径中,这里注意一下如果你的Prefab绑定的脚本中有public Object 的话 ,需要在代码中改一下。。用 Find() FindTag()这类方法在脚本中Awake()方法中来拿,不然Prefab动态加载的时候无法赋值的,如下图所示,我把封装的Prefab对象都放在了Resources/Prefab文件夹下。
OK,现在我们就需要编写我们的导出工具、在Project视图中创建Editor文件夹,接着创建脚本MyEditor 。如下图所示。
MyEditor.cs
002
usingSystem.Collections; |
003
usingUnityEditor; |
004
usingSystem.Collections.Generic; |
005
usingSystem.Xml; |
006
usingSystem.IO; |
007
usingSystem.Text; |
008
usingLitJson; |
009
publicclassMyEditor : Editor |
010
{ |
011
//将所有游戏场景导出为XML格式 |
012
[MenuItem ("GameObject/ExportXML")] |
013
staticvoidExportXML () |
014
{ |
015
stringfilepath = Application.dataPath + @"/StreamingAssets/my.xml"; |
016
if(!File.Exists (filepath)) |
017
018 |
File.Delete(filepath); |
019
} |
020
XmlDocument xmlDoc = newXmlDocument(); |
021
XmlElement root = xmlDoc.CreateElement("gameObjects"); |
022
//遍历所有的游戏场景 |
023
foreach(UnityEditor.EditorBuildSettingsScene S inUnityEditor.EditorBuildSettings.scenes) |
024
025 |
//当关卡启用 |
026
if(S.enabled) |
027
{ |
028
//得到关卡的名称 |
029
stringname = S.path; |
030
//打开这个关卡 |
031
EditorApplication.OpenScene(name); |
032
XmlElement scenes = xmlDoc.CreateElement("scenes"); |
033
scenes.SetAttribute("name",name); |
034
foreach(GameObject obj inObject.FindObjectsOfType(typeof(GameObject))) |
035
{ |
036
if(obj.transform.parent == null) |
037
038 |
XmlElement gameObject = xmlDoc.CreateElement("gameObjects"); |
039
gameObject.SetAttribute("name",obj.name); |
040
|
041
gameObject.SetAttribute("asset",obj.name + ".prefab"); |
042
XmlElement transform = xmlDoc.CreateElement("transform"); |
043
XmlElement position = xmlDoc.CreateElement("position"); |
044
XmlElement position_x = xmlDoc.CreateElement("x"); |
045
position_x.InnerText = obj.transform.position.x+""; |
046
XmlElement position_y = xmlDoc.CreateElement("y"); |
047
position_y.InnerText = obj.transform.position.y+""; |
048
XmlElement position_z = xmlDoc.CreateElement("z"); |
049
position_z.InnerText = obj.transform.position.z+""; |
050
position.AppendChild(position_x); |
051
position.AppendChild(position_y); |
052
position.AppendChild(position_z); |
053
054 |
XmlElement rotation = xmlDoc.CreateElement("rotation"); |
055
XmlElement rotation_x = xmlDoc.CreateElement("x"); |
056
rotation_x.InnerText = obj.transform.rotation.eulerAngles.x+""; |
057
XmlElement rotation_y = xmlDoc.CreateElement("y"); |
058
rotation_y.InnerText = obj.transform.rotation.eulerAngles.y+""; |
059
XmlElement rotation_z = xmlDoc.CreateElement("z"); |
060
rotation_z.InnerText = obj.transform.rotation.eulerAngles.z+""; |
061
rotation.AppendChild(rotation_x); |
062
rotation.AppendChild(rotation_y); |
063
rotation.AppendChild(rotation_z); |
064
065 |
XmlElement scale = xmlDoc.CreateElement("scale"); |
066
XmlElement scale_x = xmlDoc.CreateElement("x"); |
067
scale_x.InnerText = obj.transform.localScale.x+""; |
068
XmlElement scale_y = xmlDoc.CreateElement("y"); |
069
scale_y.InnerText = obj.transform.localScale.y+""; |
070
XmlElement scale_z = xmlDoc.CreateElement("z"); |
071
scale_z.InnerText = obj.transform.localScale.z+""; |
072
073 |
scale.AppendChild(scale_x); |
074
scale.AppendChild(scale_y); |
075
scale.AppendChild(scale_z); |
076
077 |
transform.AppendChild(position); |
078
transform.AppendChild(rotation); |
079
transform.AppendChild(scale); |
080
081 |
gameObject.AppendChild(transform); |
082
scenes.AppendChild(gameObject); |
083
root.AppendChild(scenes); |
084
xmlDoc.AppendChild(root); |
085
xmlDoc.Save(filepath); |
086
087 |
} |
088
089 |
} |
090
091 |
//刷新Project视图, 不然需要手动刷新哦 |
092
AssetDatabase.Refresh(); |
093
094 |
095 |
//将所有游戏场景导出为JSON格式 |
096
[MenuItem ("GameObject/ExportJSON")] |
097
staticvoidExportJSON () |
098
099 |
stringfilepath = Application.dataPath + @"/StreamingAssets/json.txt"; |
100
FileInfo t = newFileInfo(filepath); |
101
102 |
103 |
104 |
105 |
StreamWriter sw = t.CreateText(); |
106
107 |
StringBuilder sb = newStringBuilder (); |
108
JsonWriter writer = newJsonWriter (sb); |
109
writer.WriteObjectStart (); |
110
writer.WritePropertyName ("GameObjects"); |
111
writer.WriteArrayStart (); |
112
113 |
114 |
115 |
116 |
117 |
118 |
119 |
writer.WriteObjectStart(); |
120
writer.WritePropertyName("scenes"); |
121
writer.WriteArrayStart (); |
122
123 |
writer.WritePropertyName("name"); |
124
writer.Write(name); |
125
writer.WritePropertyName("gameObject"); |
126
127 |
128 |
129 |
130 |
131 |
132 |
writer.WriteObjectStart(); |
133
writer.WritePropertyName("name"); |
134
writer.Write(obj.name); |
135
136 |
writer.WritePropertyName("position"); |
137
writer.WriteArrayStart (); |
138
139 |
writer.WritePropertyName("x"); |
140
writer.Write(obj.transform.position.x.ToString("F5")); |
141
writer.WritePropertyName("y"); |
142
writer.Write(obj.transform.position.y.ToString("F5")); |
143
writer.WritePropertyName("z"); |
144
writer.Write(obj.transform.position.z.ToString("F5")); |
145
writer.WriteObjectEnd(); |
146
writer.WriteArrayEnd(); |
147
148 |
writer.WritePropertyName("rotation"); |
149
150 |
151 |
152 |
writer.Write(obj.transform.rotation.eulerAngles.x.ToString("F5")); |
153
154 |
writer.Write(obj.transform.rotation.eulerAngles.y.ToString("F5")); |
155
156 |
writer.Write(obj.transform.rotation.eulerAngles.z.ToString("F5")); |
157
158 |
159 |
160 |
writer.WritePropertyName("scale"); |
161
162 |
163 |
164 |
writer.Write(obj.transform.localScale.x.ToString("F5")); |
165
166 |
writer.Write(obj.transform.localScale.y.ToString("F5")); |
167
168 |
writer.Write(obj.transform.localScale.z.ToString("F5")); |
169
170 |
171 |
172 |
173 |
174 |
175 |
176 |
writer.WriteArrayEnd(); |
177
writer.WriteObjectEnd(); |
178
179 |
180 |
181 |
182 |
writer.WriteArrayEnd(); |
183
writer.WriteObjectEnd (); |
184
185 |
sw.WriteLine(sb.ToString()); |
186
sw.Close(); |
187
sw.Dispose(); |
188
AssetDatabase.Refresh(); |
189
190 |
} |
OK。此时我们就可以导出游戏场景的信息拉,注意游戏场景的需要现在Project Setting 中注册。点击 GameObject – > Export XML 和 GameObject – > ExportJson 菜单项即可开始生成。
如下图所示,场景导出完毕后,会将xml 与Json 文件保存在StreamingAssets路径下,放在这里的原因是方便移动平台移植,因为它们属于二进制文件,移动平台在读取二进制文件的路径是不一样的。一定要放在这里喔。
接着,我继续创建两个游戏场景,一个用来解析XML的场景,一个用来解析JSON的场景。
XML场景中,创建一个空的游戏对象,把XML.cs挂上去。
publicclassXML : MonoBehaviour {
// Use this for initialization
voidStart ()
//电脑和iphong上的路径是不一样的,这里用标签判断一下。
#if UNITY_EDITOR
stringfilepath = Application.dataPath +"/StreamingAssets"+"/my.xml";
#elif UNITY_IPHONE
stringfilepath = Application.dataPath +"/Raw"+"/my.xml";
#endif
//如果文件存在话开始解析。
if(File.Exists (filepath))
XmlDocument xmlDoc = newXmlDocument();
xmlDoc.Load(filepath);
XmlNodeList nodeList=xmlDoc.SelectSingleNode("gameObjects").ChildNodes;
foreach(XmlElement sceneinnodeList)
//因为我的XML是把所有游戏对象全部导出, 所以这里判断一下只解析需要的场景中的游戏对象
//JSON和它的原理类似
if(!scene.GetAttribute("name").Equals("Assets/StarTrooper.unity"))
continue;
foreach(XmlElement gameObjects inscene.ChildNodes)
stringasset = "Prefab/"+ gameObjects.GetAttribute("name");
Vector3 pos = Vector3.zero;
Vector3 rot = Vector3.zero;
Vector3 sca = Vector3.zero;
foreach(XmlElement transform ingameObjects.ChildNodes)
foreach(XmlElement prs intransform.ChildNodes)
{
if(prs.Name == "position")
{
foreach(XmlElement position inprs.ChildNodes)
switch(position.Name)
{
case"x":
pos.x = float.Parse(position.InnerText);
break;
case"y":
pos.y = float.Parse(position.InnerText);
case"z":
pos.z = float.Parse(position.InnerText);
}
}elseif(prs.Name == "rotation")
foreach(XmlElement rotation inprs.ChildNodes)
switch(rotation.Name)
case"x":
rot.x = float.Parse(rotation.InnerText);
break;
case"y":
rot.y = float.Parse(rotation.InnerText);
case"z":
rot.z = float.Parse(rotation.InnerText);
}elseif(prs.Name == "scale")
foreach(XmlElement scale inprs.ChildNodes)
switch(scale.Name)
sca.x = float.Parse(scale.InnerText);
sca.y = float.Parse(scale.InnerText);
sca.z = float.Parse(scale.InnerText);
}
//拿到 旋转 缩放 平移 以后克隆新游戏对象
GameObject ob = (GameObject)Instantiate(Resources.Load(asset),pos,Quaternion.Euler(rot));
ob.transform.localScale = sca;
// Update is called once per frame
voidUpdate ()
voidOnGUI()
if(GUI.Button(newRect(0,200,200),"XML WORLD"))
Application.LoadLevel("JSONScene");
接着JSON场景中,创建一个空的游戏对象,把JSON.cs挂上去。
02
03 |
04 |
05 |
06 |
publicclassJSON : MonoBehaviour { |
07
08 |
09 |
10 |
11 |
12 |
stringfilepath = Application.dataPath +"/StreamingAssets"+"/json.txt"; |
13
14 |
stringfilepath = Application.dataPath +"/Raw"+"/json.txt"; |
15
#endif |
16
17 |
StreamReader sr= File.OpenText(filepath); |
18
stringstrLine = sr.ReadToEnd(); |
19
JsonData jd = JsonMapper.ToObject(strLine); |
20
JsonData gameObjectArray = jd["GameObjects"]; |
21
inti,j,k; |
22
for(i = 0; i < gameObjectArray.Count; i++) |
23
24 |
JsonData senseArray = gameObjectArray["scenes"]; |
25
for(j = 0; j < senseArray.Count; j++) |
26
{ |
27
stringsceneName = (string)senseArray[j]["name"]; |
28
if(!sceneName.Equals("Assets/StarTrooper.unity")) |
29
30 |
31 |
32 |
JsonData gameObjects = senseArray[j]["gameObject"]; |
33
34 |
for(k = 0; k < gameObjects.Count; k++) |
35
36 |
stringobjectName = (string)gameObjects[k]["name"]; |
37
stringasset = "Prefab/"+ objectName; |
38
39 |
40 |
41 |
42 |
JsonData position = gameObjects[k]["position"]; |
43
JsonData rotation = gameObjects[k]["rotation"]; |
44
JsonData scale = gameObjects[k]["scale"]; |
45
46 |
pos.x = float.Parse((string)position[0]["x"]); |
47
pos.y = float.Parse((string)position[0]["y"]); |
48
pos.z = float.Parse((string)position[0]["z"]); |
49
50 |
rot.x = float.Parse((string)rotation[0]["x"]); |
51
rot.y = float.Parse((string)rotation[0]["y"]); |
52
rot.z = float.Parse((string)rotation[0]["z"]); |
53
54 |
sca.x = float.Parse((string)scale[0]["x"]); |
55
sca.y = float.Parse((string)scale[0]["y"]); |
56
sca.z = float.Parse((string)scale[0]["z"]); |
57
58 |
59 |
60 |
61 |
62 |
63 |
} |
64
65 |
66 |
67 |
68 |
69 |
voidUpdate () { |
70
71 |
72 |
73 |
74 |
75 |
|
76
77 |
Application.LoadLevel("XMLScene"); |
78
79 |
80 |
81 |
82 |
本例XML和JSON的解析与还原场景,在IOS真实设备上测试通过。
本例的下载地址:http://vdisk.weibo.com/s/k0_DE
原文链接:https://www.f2er.com/xml/299603.html
|