导出Unity场景的所有游戏对象信息,一种是XML一种是JSON
来源:互联网 发布:外国人生活知乎 编辑:程序博客网 时间:2024/05/17 07:36
导出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 。如下图所示。
因为编辑的游戏场景数量比较多,导出的时候我们需要遍历所有的游戏场景,一个一个的读取场景信息。然后取得游戏场景中所有游戏对象的Prefab的 名称 旋转 缩放 平移。有关XML的使用请大家看我的上一篇文章: Unity3D研究院之使用 C#合成解析XML与JSON(四十一) 代码中我只注释重点的部分,嘿嘿。
001
using
UnityEngine;
002
using
System.Collections;
003
using
UnityEditor;
004
using
System.Collections.Generic;
005
using
System.Xml;
006
using
System.IO;
007
using
System.Text;
008
using
LitJson;
009
public
class
MyEditor : Editor
010
{
011
//将所有游戏场景导出为XML格式
012
[MenuItem (
"GameObject/ExportXML"
)]
013
static
void
ExportXML ()
014
{
015
string
filepath = Application.dataPath +
@"/StreamingAssets/my.xml"
;
016
if
(!File.Exists (filepath))
017
{
018
File.Delete(filepath);
019
}
020
XmlDocument xmlDoc =
new
XmlDocument();
021
XmlElement root = xmlDoc.CreateElement(
"gameObjects"
);
022
//遍历所有的游戏场景
023
foreach
(UnityEditor.EditorBuildSettingsScene S
in
UnityEditor.EditorBuildSettings.scenes)
024
{
025
//当关卡启用
026
if
(S.enabled)
027
{
028
//得到关卡的名称
029
string
name = S.path;
030
//打开这个关卡
031
EditorApplication.OpenScene(name);
032
XmlElement scenes = xmlDoc.CreateElement(
"scenes"
);
033
scenes.SetAttribute(
"name"
,name);
034
foreach
(GameObject obj
in
Object.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
static
void
ExportJSON ()
098
{
099
string
filepath = Application.dataPath +
@"/StreamingAssets/json.txt"
;
100
FileInfo t =
new
FileInfo(filepath);
101
if
(!File.Exists (filepath))
102
{
103
File.Delete(filepath);
104
}
105
StreamWriter sw = t.CreateText();
106
107
StringBuilder sb =
new
StringBuilder ();
108
JsonWriter writer =
new
JsonWriter (sb);
109
writer.WriteObjectStart ();
110
writer.WritePropertyName (
"GameObjects"
);
111
writer.WriteArrayStart ();
112
113
foreach
(UnityEditor.EditorBuildSettingsScene S
in
UnityEditor.EditorBuildSettings.scenes)
114
{
115
if
(S.enabled)
116
{
117
string
name = S.path;
118
EditorApplication.OpenScene(name);
119
writer.WriteObjectStart();
120
writer.WritePropertyName(
"scenes"
);
121
writer.WriteArrayStart ();
122
writer.WriteObjectStart();
123
writer.WritePropertyName(
"name"
);
124
writer.Write(name);
125
writer.WritePropertyName(
"gameObject"
);
126
writer.WriteArrayStart ();
127
128
foreach
(GameObject obj
in
Object.FindObjectsOfType(
typeof
(GameObject)))
129
{
130
if
(obj.transform.parent ==
null
)
131
{
132
writer.WriteObjectStart();
133
writer.WritePropertyName(
"name"
);
134
writer.Write(obj.name);
135
136
writer.WritePropertyName(
"position"
);
137
writer.WriteArrayStart ();
138
writer.WriteObjectStart();
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
writer.WriteArrayStart ();
150
writer.WriteObjectStart();
151
writer.WritePropertyName(
"x"
);
152
writer.Write(obj.transform.rotation.eulerAngles.x.ToString(
"F5"
));
153
writer.WritePropertyName(
"y"
);
154
writer.Write(obj.transform.rotation.eulerAngles.y.ToString(
"F5"
));
155
writer.WritePropertyName(
"z"
);
156
writer.Write(obj.transform.rotation.eulerAngles.z.ToString(
"F5"
));
157
writer.WriteObjectEnd();
158
writer.WriteArrayEnd();
159
160
writer.WritePropertyName(
"scale"
);
161
writer.WriteArrayStart ();
162
writer.WriteObjectStart();
163
writer.WritePropertyName(
"x"
);
164
writer.Write(obj.transform.localScale.x.ToString(
"F5"
));
165
writer.WritePropertyName(
"y"
);
166
writer.Write(obj.transform.localScale.y.ToString(
"F5"
));
167
writer.WritePropertyName(
"z"
);
168
writer.Write(obj.transform.localScale.z.ToString(
"F5"
));
169
writer.WriteObjectEnd();
170
writer.WriteArrayEnd();
171
172
writer.WriteObjectEnd();
173
}
174
}
175
176
writer.WriteArrayEnd();
177
writer.WriteObjectEnd();
178
writer.WriteArrayEnd();
179
writer.WriteObjectEnd();
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挂上去。
001
using
UnityEngine;
002
using
System.Collections;
003
using
System.Xml;
004
using
System.IO;
005
public
class
XML : MonoBehaviour {
006
007
// Use this for initialization
008
void
Start ()
009
{
010
011
//电脑和iphong上的路径是不一样的,这里用标签判断一下。
012
#if UNITY_EDITOR
013
string
filepath = Application.dataPath +
"/StreamingAssets"
+
"/my.xml"
;
014
#elif UNITY_IPHONE
015
string
filepath = Application.dataPath +
"/Raw"
+
"/my.xml"
;
016
#endif
017
//如果文件存在话开始解析。
018
if
(File.Exists (filepath))
019
{
020
XmlDocument xmlDoc =
new
XmlDocument();
021
xmlDoc.Load(filepath);
022
XmlNodeList nodeList=xmlDoc.SelectSingleNode(
"gameObjects"
).ChildNodes;
023
foreach
(XmlElement scene
in
nodeList)
024
{
025
//因为我的XML是把所有游戏对象全部导出, 所以这里判断一下只解析需要的场景中的游戏对象
026
//JSON和它的原理类似
027
if
(!scene.GetAttribute(
"name"
).Equals(
"Assets/StarTrooper.unity"
))
028
{
029
continue
;
030
}
031
032
foreach
(XmlElement gameObjects
in
scene.ChildNodes)
033
{
034
035
string
asset =
"Prefab/"
+ gameObjects.GetAttribute(
"name"
);
036
Vector3 pos = Vector3.zero;
037
Vector3 rot = Vector3.zero;
038
Vector3 sca = Vector3.zero;
039
foreach
(XmlElement transform
in
gameObjects.ChildNodes)
040
{
041
foreach
(XmlElement prs
in
transform.ChildNodes)
042
{
043
if
(prs.Name ==
"position"
)
044
{
045
foreach
(XmlElement position
in
prs.ChildNodes)
046
{
047
switch
(position.Name)
048
{
049
case
"x"
:
050
pos.x =
float
.Parse(position.InnerText);
051
break
;
052
case
"y"
:
053
pos.y =
float
.Parse(position.InnerText);
054
break
;
055
case
"z"
:
056
pos.z =
float
.Parse(position.InnerText);
057
break
;
058
}
059
}
060
}
else
if
(prs.Name ==
"rotation"
)
061
{
062
foreach
(XmlElement rotation
in
prs.ChildNodes)
063
{
064
switch
(rotation.Name)
065
{
066
case
"x"
:
067
rot.x =
float
.Parse(rotation.InnerText);
068
break
;
069
case
"y"
:
070
rot.y =
float
.Parse(rotation.InnerText);
071
break
;
072
case
"z"
:
073
rot.z =
float
.Parse(rotation.InnerText);
074
break
;
075
}
076
}
077
}
else
if
(prs.Name ==
"scale"
)
078
{
079
foreach
(XmlElement scale
in
prs.ChildNodes)
080
{
081
switch
(scale.Name)
082
{
083
case
"x"
:
084
sca.x =
float
.Parse(scale.InnerText);
085
break
;
086
case
"y"
:
087
sca.y =
float
.Parse(scale.InnerText);
088
break
;
089
case
"z"
:
090
sca.z =
float
.Parse(scale.InnerText);
091
break
;
092
}
093
}
094
}
095
}
096
097
//拿到 旋转 缩放 平移 以后克隆新游戏对象
098
GameObject ob = (GameObject)Instantiate(Resources.Load(asset),pos,Quaternion.Euler(rot));
099
ob.transform.localScale = sca;
100
101
}
102
}
103
}
104
}
105
}
106
107
// Update is called once per frame
108
void
Update ()
109
{
110
111
}
112
113
void
OnGUI()
114
{
115
if
(GUI.Button(
new
Rect(0,0,200,200),
"XML WORLD"
))
116
{
117
Application.LoadLevel(
"JSONScene"
);
118
}
119
120
}
121
122
}
接着JSON场景中,创建一个空的游戏对象,把JSON.cs挂上去。
01
using
UnityEngine;
02
using
System.Collections;
03
using
System.IO;
04
using
LitJson;
05
06
public
class
JSON : MonoBehaviour {
07
08
// Use this for initialization
09
void
Start ()
10
{
11
#if UNITY_EDITOR
12
string
filepath = Application.dataPath +
"/StreamingAssets"
+
"/json.txt"
;
13
#elif UNITY_IPHONE
14
string
filepath = Application.dataPath +
"/Raw"
+
"/json.txt"
;
15
#endif
16
17
StreamReader sr = File.OpenText(filepath);
18
string
strLine = sr.ReadToEnd();
19
JsonData jd = JsonMapper.ToObject(strLine);
20
JsonData gameObjectArray = jd[
"GameObjects"
];
21
int
i,j,k;
22
for
(i = 0; i < gameObjectArray.Count; i++)
23
{
24
JsonData senseArray = gameObjectArray[i][
"scenes"
];
25
for
(j = 0; j < senseArray.Count; j++)
26
{
27
string
sceneName = (
string
)senseArray[j][
"name"
];
28
if
(!sceneName.Equals(
"Assets/StarTrooper.unity"
))
29
{
30
continue
;
31
}
32
JsonData gameObjects = senseArray[j][
"gameObject"
];
33
34
for
(k = 0; k < gameObjects.Count; k++)
35
{
36
string
objectName = (
string
)gameObjects[k][
"name"
];
37
string
asset =
"Prefab/"
+ objectName;
38
Vector3 pos = Vector3.zero;
39
Vector3 rot = Vector3.zero;
40
Vector3 sca = Vector3.zero;
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
GameObject ob = (GameObject)Instantiate(Resources.Load(asset),pos,Quaternion.Euler(rot));
59
ob.transform.localScale = sca;
60
61
}
62
63
}
64
}
65
66
}
67
68
// Update is called once per frame
69
void
Update () {
70
71
}
72
73
void
OnGUI()
74
{
75
if
(GUI.Button(
new
Rect(0,0,200,200),
"JSON WORLD"
))
76
{
77
Application.LoadLevel(
"XMLScene"
);
78
}
79
80
}
81
82
}
本例XML和JSON的解析与还原场景,在IOS真实设备上测试通过。
本例的下载地址:http://vdisk.weibo.com/s/k0_DE
雨松MOMO 祝大家学习愉快,准备睡觉,安 。欢迎讨论与学习 嘿嘿。
- 导出Unity场景的所有游戏对象信息,一种是XML一种是JSON
- 商业软件,是一种寸土必争的游戏
- 游戏是一种社会力量
- JSON是一种数据交换格式(JSON对象/JSON字符串/JSON数字/JSON数组等) -------- JSON对象是JS引擎的内置对象
- XML是一种标识语言
- Animation的二种使用方法一种是JavaCode一种是xml文件配置
- 第四章 管理是一种控制性的游戏
- 渗透性测试是一种特殊的信息安全服务
- XPath是一种XML文档的寻址语言
- 问:请问WAP是XML的一种特定格式吗?
- 定时器是线程的一种
- 玩的是一种成就感
- vector是同一种类型的对象的集合
- 汉语是唯一一种面向对象的高级语言
- 汉语是世界上唯一一种面向对象的高级语言
- javascript对象的property和prototype是这样一种关系
- javascript对象的property和prototype是这样一种关系
- javascript对象的property和prototype是这样一种关系
- strtok和wcstok分割字符串函数
- smd driver of msm
- IOS 唯一标示符
- widget 解释
- 约瑟夫环问题
- 导出Unity场景的所有游戏对象信息,一种是XML一种是JSON
- 用TiXmlDocument读取的内存中的xml存到string里
- C++的封装性、继承性和多态性概念
- Viz Artist中如何快速替换场景中的字体
- hadoop对于压缩文件的支持及算法优缺点
- Yesterday、Today、Tomorrow - 昨天、今天、明天
- DateUtils.IsPM - 判断时间是否是下午
- 两个排序数组的中位数
- 隐式类型转换