- 最后登录
- 2021-7-6
- 注册时间
- 2012-12-27
- 阅读权限
- 90
- 积分
- 76145
- 纳金币
- 53488
- 精华
- 316
|
参考:http://www.xuanyusong.com/archives/1919 http://www.omuying.com/article/48.aspx
主要功能:
1.导出场景的配置文件
2.导出当前场景中资源的AssetBundle
3.客户端从服务器获取配置文件
4.解析配置文件,并根据配置文件下载AssetBundle
5.实例化并还原场景
场景设置:将需要导出的场景资源设置为预设
将场景配置导出为XML文件- 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();
- }
- }
- }
- }
复制代码 导出结果参考:- <?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>
复制代码 将预设打包为AssetBundle,并上传到服务器
打包Assetbundle编辑器脚本:- 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();
- }
- }
复制代码 将服务器的路径修改到XML配置文件中,并将XML上传到服务器
在Unity客户端下载XML并解析,下载并实例化对应的资源- 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);
- }
- }
- }
复制代码 |
|