场景的信息保存成xml或json,并恢复场景

为了,能够动态的将场景加载至游戏中,我们首先需要做的就是,收集并保存场景中游戏对象的位置,旋转,缩放这几个基本的信息。

我们可以将对象信息保存成xml或者json两种格式。

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Text;
using LitJson;
public class MyEditor : Editor 
{	
	//将所有游戏场景导出为XML格式
	[MenuItem ("GameObject/ExportXML")]
	static void ExportXML () 
	{
		string filepath = Application.dataPath + @"/StreamingAssets/RechardTry.xml";
		if(!File.Exists (filepath))
		{
			File.Delete(filepath);
		}
		XmlDocument xmlDoc = new XmlDocument(); 
		XmlElement root = xmlDoc.CreateElement("gameObjects");
		//遍历所有的游戏场景
		foreach (UnityEditor.EditorBuildSettingsScene S in UnityEditor.EditorBuildSettings.scenes)
		{
			//当关卡启用
			if (S.enabled)
			{
				//得到关卡的名称
				string name = S.path;
				//打开这个关卡
				EditorApplication.OpenScene(name);
				XmlElement scenes = xmlDoc.CreateElement("scenes");
				scenes.SetAttribute("name",name);
				foreach (GameObject obj in Object.FindobjectsOfType(typeof(GameObject)))
				{
					if (obj.transform.parent == null)
					{
						 XmlElement gameObject = xmlDoc.CreateElement("gameObjects");
						 gameObject.SetAttribute("name",obj.name);
						
						
						 gameObject.SetAttribute("asset",obj.name + ".prefab");
						 XmlElement transform = xmlDoc.CreateElement("transform");
						 XmlElement position = xmlDoc.CreateElement("position");
						 XmlElement position_x = xmlDoc.CreateElement("x");
						 position_x.InnerText = obj.transform.position.x+"";
						 XmlElement position_y = xmlDoc.CreateElement("y");
						 position_y.InnerText = obj.transform.position.y+"";
						 XmlElement position_z = xmlDoc.CreateElement("z");
						 position_z.InnerText = obj.transform.position.z+"";
						 position.AppendChild(position_x);
						 position.AppendChild(position_y);
						 position.AppendChild(position_z);
		
						 XmlElement rotation = xmlDoc.CreateElement("rotation");
						 XmlElement rotation_x = xmlDoc.CreateElement("x");
						 rotation_x.InnerText = obj.transform.rotation.eulerAngles.x+"";
						 XmlElement rotation_y = xmlDoc.CreateElement("y");
						 rotation_y.InnerText = obj.transform.rotation.eulerAngles.y+"";
						 XmlElement rotation_z = xmlDoc.CreateElement("z");
						 rotation_z.InnerText = obj.transform.rotation.eulerAngles.z+"";
						 rotation.AppendChild(rotation_x);
						 rotation.AppendChild(rotation_y);
						 rotation.AppendChild(rotation_z);
		
						 XmlElement scale = xmlDoc.CreateElement("scale");
						 XmlElement scale_x = xmlDoc.CreateElement("x");
						 scale_x.InnerText = obj.transform.localScale.x+"";
						 XmlElement scale_y = xmlDoc.CreateElement("y");
						 scale_y.InnerText = obj.transform.localScale.y+"";
						 XmlElement scale_z = xmlDoc.CreateElement("z");
						 scale_z.InnerText = obj.transform.localScale.z+"";
		 
						 scale.AppendChild(scale_x);
						 scale.AppendChild(scale_y);
						 scale.AppendChild(scale_z);
		
						 transform.AppendChild(position);	
						 transform.AppendChild(rotation);	
						 transform.AppendChild(scale);	
		
						 gameObject.AppendChild(transform);	
						 scenes.AppendChild(gameObject);
						 root.AppendChild(scenes);
						 xmlDoc.AppendChild(root);
						 xmlDoc.Save(filepath);
						
					}
				}		
			}
		}
		//刷新Project视图, 不然需要手动刷新哦
		 AssetDatabase.Refresh();
	}
	
	//将所有游戏场景导出为JSON格式
	[MenuItem ("GameObject/ExportJSON")]
	static void ExportJSON () 
	{
		string filepath = Application.dataPath + @"/StreamingAssets/json.txt";
		FileInfo t = new FileInfo(filepath);
		if(!File.Exists (filepath))
		{
			File.Delete(filepath);
		}
		StreamWriter sw = t.CreateText();
	   
		
		StringBuilder sb = new StringBuilder ();
		JsonWriter writer = new JsonWriter (sb);
		writer.WriteObjectStart ();
		writer.WritePropertyName ("GameObjects");
		writer.WriteArrayStart ();

		foreach (UnityEditor.EditorBuildSettingsScene S in UnityEditor.EditorBuildSettings.scenes)
		{
			if (S.enabled)
			{
				string name = S.path;
				EditorApplication.OpenScene(name);
				writer.WriteObjectStart();
				writer.WritePropertyName("scenes");
				writer.WriteArrayStart ();
				writer.WriteObjectStart();
				writer.WritePropertyName("name");
				writer.Write(name);
				writer.WritePropertyName("gameObject");
				writer.WriteArrayStart ();
				
				foreach (GameObject obj in Object.FindobjectsOfType(typeof(GameObject)))
				{
					if (obj.transform.parent == null)
					{
						writer.WriteObjectStart();
						writer.WritePropertyName("name");
						writer.Write(obj.name);
						
						writer.WritePropertyName("position");
						writer.WriteArrayStart ();
						writer.WriteObjectStart();
						writer.WritePropertyName("x");
						writer.Write(obj.transform.position.x.ToString("F5"));
						writer.WritePropertyName("y");
						writer.Write(obj.transform.position.y.ToString("F5"));
						writer.WritePropertyName("z");
						writer.Write(obj.transform.position.z.ToString("F5"));
						writer.WriteObjectEnd();
						writer.WriteArrayEnd();
						
						writer.WritePropertyName("rotation");
						writer.WriteArrayStart ();
						writer.WriteObjectStart();
						writer.WritePropertyName("x");
						writer.Write(obj.transform.rotation.eulerAngles.x.ToString("F5"));
						writer.WritePropertyName("y");
						writer.Write(obj.transform.rotation.eulerAngles.y.ToString("F5"));
						writer.WritePropertyName("z");
						writer.Write(obj.transform.rotation.eulerAngles.z.ToString("F5"));
						writer.WriteObjectEnd();
						writer.WriteArrayEnd();
						
						writer.WritePropertyName("scale");
						writer.WriteArrayStart ();
						writer.WriteObjectStart();
						writer.WritePropertyName("x");
						writer.Write(obj.transform.localScale.x.ToString("F5"));
						writer.WritePropertyName("y");
						writer.Write(obj.transform.localScale.y.ToString("F5"));
						writer.WritePropertyName("z");
						writer.Write(obj.transform.localScale.z.ToString("F5"));
						writer.WriteObjectEnd();
						writer.WriteArrayEnd();
						
						writer.WriteObjectEnd();
					}
				}
				
				writer.WriteArrayEnd();
				writer.WriteObjectEnd();
				writer.WriteArrayEnd();
				writer.WriteObjectEnd();
			}
		}
		writer.WriteArrayEnd();
		writer.WriteObjectEnd ();

	
		sw.WriteLine(sb.ToString());
		sw.Close();
		sw.dispose();
		AssetDatabase.Refresh();
	}
}


在要导出游戏场景信息前,需要做以下几件事情

1、在Assets下创建一个StreamingAssets文件

2、将场景加入到Build setting中

3、将MyEditor文件放在Assets/Editor下,如果Editor文件不存在,创建一个

4、创建一个Resources文件夹,然后再在Resources文件夹下创建一个Prefab文件夹,并将场景zhong

所有的对象都变成prefab纺织在Prefab文件夹下。



然后,我们可以利用创建的xml文件或者json文件来恢复我们需要的场景了。

1、新建一个Scene文件,命名为xml或Json

2、在该Scene中新建一个空对象,命名为RecoveryObj。

3、创建XML.cs文件或者json.cs文件并作为RecoveryObj对象的组件。

文件代码如下:

xml.cs

using UnityEngine;
using System.Collections;
using System.Xml;
using System.IO;
public class XML : MonoBehavIoUr {

	// Use this for initialization
	void Start () 
	{
		
//电脑和iphong上的路径是不一样的,这里用标签判断一下。
#if UNITY_EDITOR
		string filepath = Application.dataPath +"/StreamingAssets"+"/my.xml";
#elif UNITY_IPHONE
	  string filepath = Application.dataPath +"/Raw"+"/my.xml";
#endif
        //如果文件存在话开始解析。	
		if(File.Exists (filepath))
		{
			XmlDocument xmlDoc = new XmlDocument();
		 	xmlDoc.Load(filepath);
		 	XmlNodeList nodeList=xmlDoc.SelectSingleNode("gameObjects").ChildNodes;
			foreach(XmlElement scene  in nodeList)
			{		
				//因为我的XML是把所有游戏对象全部导出, 所以这里判断一下只解析需要的场景中的游戏对象
				//JSON和它的原理类似
				if(!scene.GetAttribute("name").Equals("Assets/StarTrooper.unity"))
				{
					continue;
				}
				
				
				foreach(XmlElement gameObjects in scene.ChildNodes)
				{
					
					string asset = "Prefab/" + gameObjects.GetAttribute("name");
					Vector3 pos = Vector3.zero;
					Vector3 rot = Vector3.zero;
					Vector3 sca = Vector3.zero;
					foreach(XmlElement transform in gameObjects.ChildNodes)
					{
						foreach(XmlElement prs in transform.ChildNodes)
						{
							if(prs.Name == "position")
							{
								foreach(XmlElement position in prs.ChildNodes)	
								{
									switch(position.Name)
									{
									case "x":
										pos.x = float.Parse(position.InnerText);
										break;
									case "y":
										pos.y = float.Parse(position.InnerText);
										break;
									case "z":
										pos.z = float.Parse(position.InnerText);
										break;
								}
							}
						}else if(prs.Name == "rotation")
						{
							foreach(XmlElement rotation in prs.ChildNodes)	
							{
								switch(rotation.Name)
								{
								case "x":
									rot.x = float.Parse(rotation.InnerText);
									break;
								case "y":
									rot.y = float.Parse(rotation.InnerText);
									break;
								case "z":
									rot.z = float.Parse(rotation.InnerText);
									break;
								}
							}		
						}else if(prs.Name == "scale")
						{
							foreach(XmlElement scale in prs.ChildNodes)	
							{
								switch(scale.Name)
								{
								case "x":
									sca.x = float.Parse(scale.InnerText);
									break;
								case "y":
									sca.y = float.Parse(scale.InnerText);
									break;
								case "z":
									sca.z = float.Parse(scale.InnerText);
									break;
								}
							}		
						}
					}
					
					//拿到 旋转 缩放 平移 以后克隆新游戏对象
					GameObject ob = (GameObject)Instantiate(Resources.Load(asset),pos,Quaternion.Euler(rot));
					ob.transform.localScale = sca;
					
					}
			}
			}
		}	
	}
	
	// Update is called once per frame
	void Update () 
	{
	
	}
	
	void OnGUI()
	{
		if(GUI.Button(new Rect(0,200,200),"XML WORLD"))
		{
			Application.LoadLevel("JSONScene");
		}
		
	}

}

json.cs如下:

using UnityEngine;
using System.Collections;
using System.IO;
using LitJson;

public class JSON : MonoBehavIoUr {

	// Use this for initialization
	void Start ()
	{
#if UNITY_EDITOR
	  string filepath = Application.dataPath +"/StreamingAssets"+"/json.txt";
#elif UNITY_IPHONE
	  string filepath = Application.dataPath +"/Raw"+"/json.txt";
#endif	
	   
		StreamReader sr  = File.OpenText(filepath);
		string  strLine = sr.ReadToEnd();
	   JsonData jd = JsonMapper.ToObject(strLine);
	   JsonData gameObjectArray = jd["GameObjects"];
		int i,j,k;
		for (i = 0; i < gameObjectArray.Count; i++)
		{
	 	   JsonData senseArray = gameObjectArray[i]["scenes"];
		   for (j = 0; j < senseArray.Count; j++)
	   	   {
				string sceneName = (string)senseArray[j]["name"];
				if(!sceneName.Equals("Assets/StarTrooper.unity"))
				{
					continue;
				}
				JsonData gameObjects = senseArray[j]["gameObject"];
				
				for (k = 0; k < gameObjects.Count; k++)
				{
					string objectName = (string)gameObjects[k]["name"];
					string asset = "Prefab/" + objectName;
					Vector3 pos = Vector3.zero;
					Vector3 rot = Vector3.zero;
					Vector3 sca = Vector3.zero;
					
					
					JsonData position = gameObjects[k]["position"];
					JsonData rotation = gameObjects[k]["rotation"];
					JsonData scale = gameObjects[k]["scale"];
					
					pos.x = float.Parse((string)position[0]["x"]);
					pos.y = float.Parse((string)position[0]["y"]);
					pos.z = float.Parse((string)position[0]["z"]);

					rot.x = float.Parse((string)rotation[0]["x"]);
					rot.y = float.Parse((string)rotation[0]["y"]);
					rot.z = float.Parse((string)rotation[0]["z"]);
				
					sca.x = float.Parse((string)scale[0]["x"]);
					sca.y = float.Parse((string)scale[0]["y"]);
					sca.z = float.Parse((string)scale[0]["z"]);
					
					GameObject ob = (GameObject)Instantiate(Resources.Load(asset),Quaternion.Euler(rot));
					ob.transform.localScale = sca;
					
				}
				
		   }
		}
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	void OnGUI()
	{
		if(GUI.Button(new Rect(0,"JSON WORLD"))
		{
			Application.LoadLevel("XMLScene");
		}
		
	}

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇