参考: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:

<?xml version="1.0" encoding="utf-8"?>
<root>
<scene sceneName="DongTaiJiaZaiTest">
<gameObject objectName="Box" objectAssetURL="Box">
<transform>
<position x="-1.293883" y="-0.07" z="1.41" />
<rotation x="270" y="0" z="0" />
<scale x="1" y="1" z="1" />
</transform>
</gameObject>
<gameObject objectName="meinv" objectAssetURL="meinv">
<transform>
<position x="-1.75" y="1.36" z="11.28" />
<rotation x="0" y="97.43578" z="0" />
<scale x="1.09" y="1.09" z="1.09" />
</transform>
</gameObject>
<gameObject objectName="Envirment" objectAssetURL="Envirment">
<transform>
<position x="0" y="0" z="0" />
<rotation x="0" y="0" z="0" />
<scale x="1" y="1" z="1" />
</transform>
</gameObject>
<gameObject objectName="RigidBodyFPSController" objectAssetURL="RigidBodyFPSController">
<transform>
<position x="4.89" y="1.46" z="0.87" />
<rotation x="0" y="253.2478" z="0" />
<scale x="1" y="1" z="1" />
</transform>
</gameObject>
<gameObject objectName="Sphere" objectAssetURL="Sphere">
<transform>
<position x="-2.63" y="3.28" z="-3.95" />
<rotation x="270" y="0" z="0" />
<scale x="1" y="1" z="1" />
</transform>
</gameObject>
</scene>
</root>
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" + ".unity3d";
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);
}
} }

(转)Unity 导出XML配置文件,动态加载场景的更多相关文章

  1. C#遍历XML文件动态加载菜单

    通过遍历XML文件动态加载菜单,顺便利用WebBrowser控件实现一个简单的桌面浏览器 效果如下: 代码如下: XMLFile1.xml <?xml version="1.0&quo ...

  2. Unity3d 动态加载场景物件与缓存池的使用

    聊聊Unity3d动态加载场景物件那些事儿. 众所周知,在策划或美术设计完游戏场景地图后,一个场景中可能会存在成千上万个小的物件,比如石头,木箱子,油桶,栅栏等等等等,这些物件并不是游戏中的道具,仅仅 ...

  3. android sax解析xml 文件 动态加载标题

    要解决一个问题 : 问题描述为 把标题动态的加载到 listView子布局中 我们首先通过 java程序写一个把标题写到xml文件的程序.这个程序会在以后讲解. 现在截图 已经写好的xm文件格式如下 ...

  4. Unity实现精灵资源动态加载

    private Sprite LoadSourceSprite(string relativePath) {         //把资源加载到内存中         UnityEngine.Objec ...

  5. IDEA设置maven修改settings.xml配置文件无法加载仓库

    作为初学者配置maven一般网上搜索.然后你就看到各种配置文件片段,首先配置镜像,然后配置仓库.完事后再IDEA里面配置下maven的路径和配置文件路径. 这些文章属实坑爹,完全没讲一个重要的配置就是 ...

  6. 基于xml 实现动态加载权限功能树列表---EFSFrame企业级开发架构

    在学习EFSFrame框架的过程中,感触最深的就是通过xml来实现前台与后台数据的交互,页面设计灵活,不用管后台如何写的,前台与后台的交互唯一的交互通道都是xml,在我们需要添加页面.添加规定的格式的 ...

  7. java基于xml配置的通用excel单表数据导入组件(二、xml配置文件解析加载)

    1.BN_ImportExcel.java 对应xml主节点属性 package XXXXX.manage.importexcel; import java.io.Serializable; impo ...

  8. Spring IoC容器 XML 配置与加载

    IoC 容器 XML 配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&qu ...

  9. Unity Lightmap动态加载研究

    什么情况下需要Lightmap? 移动平台上目前暂时还不能开实时光影效果,会卡成幻灯片.所以就需要将光影烘焙到贴图上. 什么情况下需要动态加载Lightmap? 1.当项目抛弃了Unity的多场景模式 ...

随机推荐

  1. 启动、关闭tomcat脚本

    #[root@node1 ~]# vim /etc/init.d/tomcat #!/bin/bash # Init file for Tomcat server daemon # # chkconf ...

  2. 【转载】游戏并发编程的讨论 & Nodejs并发性讨论 & 语法糖术语

    知乎上这篇文章对于游戏后端.性能并发.nodejs及scala等语言的讨论,很好,值得好好看. https://www.zhihu.com/question/21971645 经常了解一些牛逼技术人员 ...

  3. 转:http2的资料与使用

    https://imququ.com/post/http2-resource.html

  4. Windows下编译vpx获得各个项目VS2010解决方案的步骤

    最近研究了一下几种常见的视频编码器:x264,x265,vpx.本文简单记录一下它们的编译方法. x264,x265,vpx这三个开源的视频编码器可以说是当今“最火”的视频编码器.x264现在占据着H ...

  5. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-Switch Case语句是否会自动跳转到下一个

    在C#中,每一个case后面必须有break,所以输出1,也就是如果a=0,则只会执行case=0的那一段,当等于1之后不会继续.   在TwinCAT中,虽然CASE语句没有break,但是实际上不 ...

  6. Android平台Camera实时滤镜实现方法探讨(十)--代码地址以及简单介绍(20160118更新)

    简单做了个相机和图片编辑模块,时间原因非常多功能还没有做.尚有BUG,见谅,将在以后抽时间改动 代码地址 PS:请点个Star^-^ --------------------------------- ...

  7. Androidproject师进阶之路 :《Android开发进阶:从小工到专家》上市啦!

    封面 文件夹1 文件夹2 - 当当购买链接 - 京东购买链接 为什么写这本书 写这本书的念头由来已久了. 或许是从我打算写<Android源代码设计模式解析与实战>那时起就萌生了这个念头, ...

  8. HDU 4925 Apple Tree(推理)

    HDU 4925 Apple Tree 题目链接 题意:给一个m*n矩阵种树,每一个位置能够选择种树或者施肥,假设种上去的位置就不能施肥,假设施肥则能让周围果树产量乘2.问最大收益 思路:推理得到肯定 ...

  9. 一个请求在Struts2框架中的处理的步骤

  10. C#创建一个Window服务

    Window服务介绍 Microsoft Windows 服务能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示 ...