博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)Unity 导出XML配置文件,动态加载场景
阅读量:5117 次
发布时间:2019-06-13

本文共 13963 字,大约阅读时间需要 46 分钟。

参考:http://www.xuanyusong.com/archives/1919

http://www.omuying.com/article/48.aspx
 
主要功能:
1.导出场景的配置文件
2.导出当前场景中资源的AssetBundle
3.客户端从服务器获取配置文件
4.解析配置文件,并根据配置文件下载AssetBundle
5.实例化并还原场景
 
1.场景设置:将需要导出的场景资源设置为预设
 
2.将场景配置导出为XML文件
 

[code]csharpcode:

using UnityEngine;using UnityEditor;using System.Collections;using System.Collections.Generic;using System.Xml;using System.IO;using System.Text;public class ExportSceneToXml : Editor {	[MenuItem("Assets/Export Scene To XML From Selection")]	static void ExportXML()	{		string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "xml");		if (path.Length != 0) 		{			Object[] selectedAssetList = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);						//遍历所有的游戏对象			foreach (Object selectObject in selectedAssetList) 			{				// 场景名称				string sceneName = selectObject.name;				// 场景路径				string scenePath = AssetDatabase.GetAssetPath(selectObject);				// 场景文件				//string xmlPath = path; //Application.dataPath + "/AssetBundles/Prefab/Scenes/" + sceneName + ".xml";				// 如果存在场景文件,删除				if(File.Exists(path)) File.Delete(path);				// 打开这个关卡				EditorApplication.OpenScene(scenePath);				XmlDocument xmlDocument = new XmlDocument();				// 创建XML属性				XmlDeclaration xmlDeclaration = xmlDocument.CreateXmlDeclaration("1.0", "utf-8", null);				xmlDocument.AppendChild(xmlDeclaration);				// 创建XML根标志				XmlElement rootXmlElement = xmlDocument.CreateElement("root");				// 创建场景标志				XmlElement sceneXmlElement = xmlDocument.CreateElement("scene");				sceneXmlElement.SetAttribute("sceneName", sceneName);								foreach (GameObject sceneObject in Object.FindObjectsOfType(typeof(GameObject)))				{					// 如果对象是激活状态					if (sceneObject.transform.parent == null && sceneObject.activeSelf)					{						// 判断是否是预设						if(PrefabUtility.GetPrefabType(sceneObject) == PrefabType.PrefabInstance)						{							// 获取引用预设对象							Object prefabObject = EditorUtility.GetPrefabParent(sceneObject);							if(prefabObject != null)							{								XmlElement gameObjectXmlElement = xmlDocument.CreateElement("gameObject");								gameObjectXmlElement.SetAttribute("objectName", sceneObject.name);								gameObjectXmlElement.SetAttribute("objectAssetURL",  prefabObject.name);																XmlElement transformXmlElement = xmlDocument.CreateElement("transform");																// 位置信息								XmlElement positionXmlElement = xmlDocument.CreateElement("position");								positionXmlElement.SetAttribute("x", sceneObject.transform.position.x.ToString());								positionXmlElement.SetAttribute("y", sceneObject.transform.position.y.ToString());								positionXmlElement.SetAttribute("z", sceneObject.transform.position.z.ToString());																// 旋转信息								XmlElement rotationXmlElement = xmlDocument.CreateElement("rotation");								rotationXmlElement.SetAttribute("x", sceneObject.transform.rotation.eulerAngles.x.ToString());								rotationXmlElement.SetAttribute("y", sceneObject.transform.rotation.eulerAngles.y.ToString());								rotationXmlElement.SetAttribute("z", sceneObject.transform.rotation.eulerAngles.z.ToString());																// 缩放信息								XmlElement scaleXmlElement = xmlDocument.CreateElement("scale");								scaleXmlElement.SetAttribute("x", sceneObject.transform.localScale.x.ToString());								scaleXmlElement.SetAttribute("y", sceneObject.transform.localScale.y.ToString());								scaleXmlElement.SetAttribute("z", sceneObject.transform.localScale.z.ToString());																transformXmlElement.AppendChild(positionXmlElement);								transformXmlElement.AppendChild(rotationXmlElement);								transformXmlElement.AppendChild(scaleXmlElement);    																gameObjectXmlElement.AppendChild(transformXmlElement);								sceneXmlElement.AppendChild(gameObjectXmlElement);							}						}					}				}				rootXmlElement.AppendChild(sceneXmlElement);				xmlDocument.AppendChild(rootXmlElement);				// 保存场景数据				xmlDocument.Save(path);				// 刷新Project视图				AssetDatabase.Refresh();			}		}	}}

导出结果参考:

[code]xmlcode:

3.将预设打包为AssetBundle,并上传到服务器
打包Assetbundle编辑器脚本:

[code]csharpcode:

using UnityEngine;using System.Collections;using UnityEditor;public class Test : Editor{    [MenuItem("Custom Editor/Create AssetBunldes Main For Android")]    static void CreateAssetBunldesMainForAndroid()    {        //获取在Project视图中选择的所有游戏对象        Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);        //遍历所有的游戏对象        foreach (Object obj in SelectedAsset)        {            //本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径            //StreamingAssets是只读路径,不能写入            //服务器下载:就不需要放在这里,服务器上客户端用www类进行下载。            string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + "Android" + ".assetbundle";            if (BuildPipeline.BuildAssetBundle(obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies, BuildTarget.Android))            {                Debug.Log(obj.name + "资源打包成功");            }            else            {                Debug.Log(obj.name + "资源打包失败");            }        }        //刷新编辑器        AssetDatabase.Refresh();    }    [MenuItem("Custom Editor/Create AssetBunldes Main For iPhone")]    static void CreateAssetBunldesMainForiPhone()    {        //获取在Project视图中选择的所有游戏对象        Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);        //遍历所有的游戏对象        foreach (Object obj in SelectedAsset)        {            string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + "iPhone" + ".assetbundle";            if (BuildPipeline.BuildAssetBundle(obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies, BuildTarget.iPhone))            {                Debug.Log(obj.name + "资源打包成功");            }            else            {                Debug.Log(obj.name + "资源打包失败");            }        }        //刷新编辑器        AssetDatabase.Refresh();    }    [MenuItem("Custom Editor/Create AssetBunldes ALL For Android")]    static void CreateAssetBunldesALLForAndroid()    {        Caching.CleanCache();        string Path = Application.dataPath + "/StreamingAssets/ALLAndroid.assetbundle";        Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);        foreach (Object obj in SelectedAsset)        {            Debug.Log("Create AssetBunldes name :" + obj);        }        //这里注意第二个参数就行        if (BuildPipeline.BuildAssetBundle(null, SelectedAsset, Path, BuildAssetBundleOptions.CollectDependencies, BuildTarget.Android))        {            AssetDatabase.Refresh();        }        else        {        }    }    [MenuItem("Custom Editor/Create AssetBunldes ALL For iPhone")]    static void CreateAssetBunldesALLForiPhone()    {        Caching.CleanCache();        string Path = Application.dataPath + "/StreamingAssets/ALLiPhone.assetbundle";        Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);        foreach (Object obj in SelectedAsset)        {            Debug.Log("Create AssetBunldes name :" + obj);        }        //这里注意第二个参数就行        if (BuildPipeline.BuildAssetBundle(null, SelectedAsset, Path, BuildAssetBundleOptions.CollectDependencies, BuildTarget.iPhone))        {            AssetDatabase.Refresh();        }        else        {        }    }    [MenuItem("Custom Editor/Create Scene For Android")]    static void CreateSceneALLForAndroid()    {        Caching.CleanCache();        Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);        foreach (Object obj in SelectedAsset)        {            string Path = Application.dataPath + "/StreamingAssets/" + obj.name + "Android" + ".";            string[] levels = { @"Assets/Scenes/ExportedScene/" + obj.name + ".unity" };            BuildPipeline.BuildPlayer(levels, Path, BuildTarget.Android, BuildOptions.BuildAdditionalStreamedScenes);            Debug.Log("Craete Scene" + Path + "Complete!!");        }        AssetDatabase.Refresh();    }    [MenuItem("Custom Editor/Create Scene For iPhone")]    static void CreateSceneALLForiPhone()    {        Caching.CleanCache();        Object[] SelectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);        foreach (Object obj in SelectedAsset)        {            string Path = Application.dataPath + "/StreamingAssets/" + obj.name + "iPhone" + ".unity3d";            string[] levels = { @"Assets/Scenes/ExportedScene/" + obj.name + ".unity" };            BuildPipeline.BuildPlayer(levels, Path, BuildTarget.iPhone, BuildOptions.BuildAdditionalStreamedScenes);            Debug.Log("Craete Scene" + Path + "Complete!!");        }        AssetDatabase.Refresh();    }}
 
4.将服务器的路径修改到XML配置文件中,并将XML上传到服务器
 
5.在Unity客户端下载XML并解析,下载并实例化对应的资源

[code]csharpcode:

using UnityEngine;using System.Collections;using System.IO;using System.Collections.Generic;using System.Xml;public class GetXMLDoc : MonoBehaviour{	string filePath;	public string XMLDocURL = "http://************.xml";	void Awake ()	{		filePath = Application.persistentDataPath + "/XMLDoc1028.xml";		if (File.Exists (filePath)) {			File.Delete (filePath);		}		WWW www = new WWW (XMLDocURL);		StartCoroutine (DownloadXMLDoc (www));	}	IEnumerator DownloadXMLDoc (WWW www)	{		yield return www;		if (www.isDone) {			Debug.Log ("WWW is done");			byte[] bts = www.bytes;			int length = bts.Length;			CreateXMLDoc (filePath, bts, length);		}	}	void CreateXMLDoc (string path, byte[] info, int lenth)	{		Debug.Log ("Start to create XML");		Stream sw;		FileInfo t = new FileInfo (path);		if (!t.Exists) {			sw = t.Create ();		} else {			return;		}		sw.Write (info, 0, lenth);		sw.Close ();		sw.Dispose ();		Debug.Log ("XML create sucess");		LoadScene ();//        下载完毕之后可以读取并进行实例化了	}	void LoadScene ()	{		Debug.Log ("开始加载");		if (File.Exists (filePath)) {			XmlDocument xmlDoc = new XmlDocument ();			xmlDoc.Load (filePath);			XmlNodeList nodeList = xmlDoc.SelectSingleNode ("root").ChildNodes;			foreach (XmlElement scene  in nodeList) {				//因为我的XML是把所有游戏对象全部导出, 所以这里判断一下只解析需要的场景中的游戏对象				//JSON和它的原理类似//                if (!scene.GetAttribute("name").Equals("Assets/StarTrooper.unity"))//                {//                    continue;//                } 				foreach (XmlElement gameObjects in scene.ChildNodes) {//                    取得资源地址					string assetRUL = gameObjects.GetAttribute ("objectAssetURL");					string assetName = gameObjects.GetAttribute ("objectName");					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") {								pos.x = float.Parse(prs.GetAttribute("x"));								pos.y = float.Parse(prs.GetAttribute("y"));								pos.z = float.Parse(prs.GetAttribute("z"));//								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") {								rot.x = float.Parse (prs.GetAttribute("x"));								rot.y = float.Parse(prs.GetAttribute("y"));								rot.z = float.Parse(prs.GetAttribute("z"));//								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") {								sca.x = float.Parse (prs.GetAttribute("x"));								sca.y = float.Parse(prs.GetAttribute("y"));								sca.z = float.Parse(prs.GetAttribute("z"));//								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;//									}//								}							}						}						Debug.Log ("准备下载:" + assetRUL);//                        开始下载并实例化对象						Debug.Log (assetName + ":pos=" + pos);						Debug.Log (assetName + ":rot=" + pos);						Debug.Log (assetName + ":sca=" + pos);						StartCoroutine (DownloadAsset (new WWW (assetRUL), pos, rot, sca));						//拿到 旋转 缩放 平移 以后克隆新游戏对象//                        GameObject ob = (GameObject)Instantiate(Resources.Load(asset), pos, Quaternion.Euler(rot));//                        ob.transform.localScale = sca;                     					}				}			}		}	}	IEnumerator DownloadAsset (WWW www, Vector3 pos, Vector3 rot, Vector3 sca)	{		yield return www;		if (www.isDone) {//            yield return Instantiate(www.assetBundle.mainAsset,pos,pos,Quaternion.Euler(rot));			GameObject ob = (GameObject)Instantiate (www.assetBundle.mainAsset, pos, Quaternion.Euler (rot));			ob.transform.localScale = sca;			www.assetBundle.Unload (false);		}	}}

 

转载于:https://www.cnblogs.com/backlighting/p/5061527.html

你可能感兴趣的文章
Vue_(组件通讯)子组件向父组件传值
查看>>
jvm参数
查看>>
我对前端MVC的理解
查看>>
Silverlight实用窍门系列:19.Silverlight调用webservice上传多个文件【附带源码实例】...
查看>>
2016.3.31考试心得
查看>>
mmap和MappedByteBuffer
查看>>
Linux的基本操作
查看>>
转-求解最大连续子数组的算法
查看>>
对数器的使用
查看>>
【ASP.NET】演绎GridView基本操作事件
查看>>
ubuntu无法解析主机错误与解决的方法
查看>>
尚学堂Java面试题整理
查看>>
MySQL表的四种分区类型
查看>>
[BZOJ 3489] A simple rmq problem 【可持久化树套树】
查看>>
STM32单片机使用注意事项
查看>>
swing入门教程
查看>>
好莱坞十大导演排名及其代表作,你看过多少?
查看>>
Loj #139
查看>>
hihocoder1187 Divisors
查看>>
Azure 托管镜像和非托管镜像对比
查看>>