Unity3D之场景导出(json格式或xml格式)--(1)

来源:互联网 发布:淘宝客服培训计划表 编辑:程序博客网 时间:2024/05/18 05:03

接下来将为大家分享一下unity3d方面的基本开发技巧,一方面我也是刚刚接触到unity3d的开发,作为笔记;另一方面,也希望更多的朋友,来指导我,大家来研究学习,共同进步。好了,废话不说,下面就讨论今天主题,unity3d之场景资源的导出,并根据导出格式加载这些资源。另外还想说的一点就是,我现在从事的项目,资源导出过于复杂,导出的格式是一种自定义的格式,类似json。个人觉得这样的缺点不言而喻,这样做不仅增加导出时候得定义这种数据格式,解析时候还必须按照这种格式来解析数据格式,瞬间增加场景资源导出和导入的复杂度。我们再项目开发过程中,一般使用c#或js,这两种脚本语言都对解析json和xml提供了良好支持,为什么还要去自定义一种格式呢?画蛇添足。虽然我今天将提供两种格式资源导出,但个人还是建议使用json格式这种数据格式,因为xml是一种有严格开始和结束标记符数据格式,对于一个大型项目,我们导出资源文件将会比较繁琐,相对另一种json格式就会简洁很多,而且容易被理解。下面就分别给出这两种格式资源处理方式:

1. 资源导出

资源的导出将使用unity3d一些编辑类,首先说说,项目一般制作流程是美术制作好场景,当然包含场景内部的各种模型资源,场景内模型一般都是并排放入场景层次视图下的,所有的模型的父类都等于Null,这样做事为了方便场景资源的导出处理,当然也可根据情况特殊处理。下面给出这个编辑器类:


using UnityEngine;using System.Collections;using UnityEditor;using System.Collections.Generic;using System.Xml;using System.IO;using System.Text;using LitJson;public class SceneEditor : Editor{/// <summary>    /// 将所有游戏场景导出为xml格式/// </summary>[MenuItem ("Tool/ExportSceneResXML")]public static void ExportXML (){        string filepath = Application.dataPath + @"/SceneData/sceneXml.xml";if(!File.Exists (filepath)){File.Delete(filepath);}        // 创建xml文档类XmlDocument xmlDoc = new XmlDocument();XmlElement root = xmlDoc.CreateElement("RootObject");// 遍历所有的游戏场景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();}/// <summary>    /// 将所有游戏场景导出为json格式/// </summary>    [MenuItem("Tool/ExportSceneResJSON")]public static void ExportJSON () {string filepath = Application.dataPath + @"/SceneData/sceneJson.txt";      FileInfo fileInfo = new FileInfo(filepath);if(!File.Exists (filepath)){File.Delete(filepath);}        StreamWriter sw = fileInfo.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();}}


这段代码放入项目Editor目录下面,然后重启IDE,便会发现菜单按钮多一个Tool菜单,这个菜单下面有两个子菜单,分别为:ExportSceneResXML,ExportSceneResJSON
,这两个菜单分别是导出资源为XML格式和JSON格式。
2. 资源加载
资源加载其实就是对导出资源的逆运算,加载配置文件,实例化场景资源游戏对象,渲染出场景过程,下面给出加Json格式场景资源,XML格式资源的加载也类似,这里就不再给出,如有疑问可以共同讨论。
using UnityEngine;using System.Collections;using System.IO;using LitJson;public class JSON : MonoBehaviour {void Start (){    string filepath = Application.dataPath +"/SceneData"+"/json.txt";        // 解析JSON    StreamReader sr  = File.OpenText(filepath);string  strLine = sr.ReadToEnd();    JsonData josn = JsonMapper.ToObject(strLine);        JsonData gameObjectArray = josn["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"];JsonData gameObjects = senseArray[j]["gameObject"];for (k = 0; k < gameObjects.Count; k++){string objectName = (string)gameObjects[k]["name"];                    // 这里只是从本地加载,如果是远程资源,需要拼出资源加载路径string asset = "Prefab/" + objectName;                    // 资源Transform属性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 obj = (GameObject)Instantiate(Resources.Load(asset),pos,Quaternion.Euler(rot));obj.transform.localScale = sca;}   }}}}
在加载场景是,必须在场景内放入一个空GameObject对象,然后,将上面解析游戏对象脚本挂在该游戏对象上,加载场景时就会加载该场景所有资源,前提是必须保证配置文件和资源相对路径正确。
最后,至于XML格式的数据,这里就不列举了。


原创粉丝点击