Unity微端場景載入(二)場景資源的下載和顯示
阿新 • • 發佈:2019-01-31
上文中我們已經把場景中的結點全部自動完成打包,生產的有一批的資源包和結點配置檔案.Xml,我們需要把資源和配置檔案上傳到網路上,專案製作中購買了百度網盤,上傳到了網盤上,然後需要記錄每一個資源以及配置檔案的連結路徑,可儲存成txt檔案,然後一起上傳上去。
在資源下載前先將Xml檔案和txt檔案下載下來,這樣就知道了每個節點位置資訊,以及節點資源的連結資訊,具體程式碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; using System.Collections; using System.Xml; using System.IO; class DynamicCreateNode : MonoBehaviour { public string xmlPath; public string bundlesUrl; private XmlDocument xmlDocument; private XmlNodeList xmlNodeList; private Queue<string> urlQueue; private string[] urlInfo; private bool beginLoad; private bool IsLoad; private int threadCount; private string line; private string url; private string version; void Start() { beginLoad = false; threadCount = 0; xmlDocument = new XmlDocument(); urlQueue = new Queue<string>(); StartCoroutine(DownLoadXml()); StartCoroutine(DownLoadText()); } void Update() { if (beginLoad && threadCount < 10 && IsLoad) { StartCoroutine(DownLoadBundles()); threadCount++; } } IEnumerator DownLoadBundles() { int count = urlQueue.Count; while (urlQueue.Count > 0 && urlQueue.Count == count) { line = urlQueue.Dequeue(); urlInfo = line.Split('\t'); if (urlInfo != null) { url = urlInfo[0]; version = urlInfo[1]; } int intVer = int.Parse(version); AssetBundle bundle = null; WWW www = WWW.LoadFromCacheOrDownload(url, intVer); yield return www; if (www.error != null) { Debug.Log("www error = " + www.error); } if (www.assetBundle.mainAsset != null) bundle = www.assetBundle; if (bundle.mainAsset != null) { // UnityEngine.Object prefab = bundle.LoadAsset(bundle.mainAsset.name) as UnityEngine.Object; Debug.Log("www.assetBundle name = " + bundle.mainAsset.name + " www url = " + url); foreach (XmlNode xmlNode in xmlNodeList) { string gameObjectName = xmlNode.Attributes["objectName"].Value; string prefabName = xmlNode.Attributes["objectAsset"].Value; string objectGuid = xmlNode.Attributes["objectGuId"].Value; if (prefabName == bundle.mainAsset.name) { GameObject obj = GameObject.Find(objectGuid); UnityEngine.Object prefab = bundle.LoadAsset(bundle.mainAsset.name) as UnityEngine.Object; if (prefab && obj) { Debug.Log("prefab name = " + prefab.name); GameObject loadObj = (GameObject)GameObject.Instantiate(prefab); loadObj.transform.position = obj.transform.position; loadObj.transform.localScale = obj.transform.localScale; loadObj.transform.rotation = obj.transform.rotation; loadObj.transform.parent = obj.transform.parent; loadObj.name = gameObjectName; Destroy(obj); } } } if (bundle.mainAsset.name != null) { bundle.mainAsset.name = null; } count = urlQueue.Count; } if (www != null) { www.Dispose(); www = null; } if (bundle) { bundle.Unload(false); } } } IEnumerator DownLoadXml() { WWW www = new WWW(xmlPath); yield return www; byte[] array = www.bytes; MemoryStream stream = new MemoryStream(array); //convert stream 2 string //StreamReader reader = new StreamReader(stream); xmlDocument.Load(stream); // 使用 XPATH 獲取所有 gameObject 節點 xmlNodeList = xmlDocument.SelectNodes("//gameObject"); foreach (XmlNode xmlNode in xmlNodeList) { string gameObjectName = xmlNode.Attributes["objectName"].Value; string prefabName = xmlNode.Attributes["objectAsset"].Value; string parentName = xmlNode.Attributes["objectParent"].Value; string objectGuid = xmlNode.Attributes["objectGuId"].Value; GameObject gameObject = new GameObject(prefabName); // 使用 XPATH 獲取 位置、旋轉、縮放資料 XmlNode positionXmlNode = xmlNode.SelectSingleNode("descendant::position"); XmlNode rotationXmlNode = xmlNode.SelectSingleNode("descendant::rotation"); XmlNode scaleXmlNode = xmlNode.SelectSingleNode("descendant::scale"); if (positionXmlNode != null && rotationXmlNode != null && scaleXmlNode != null) { gameObject.transform.position = new Vector3(float.Parse(positionXmlNode.Attributes["x"].Value), float.Parse(positionXmlNode.Attributes["y"].Value), float.Parse(positionXmlNode.Attributes["z"].Value)); gameObject.transform.rotation = Quaternion.Euler(new Vector3(float.Parse(rotationXmlNode.Attributes["x"].Value), float.Parse(rotationXmlNode.Attributes["y"].Value), float.Parse(rotationXmlNode.Attributes["z"].Value))); gameObject.transform.localScale = new Vector3(float.Parse(scaleXmlNode.Attributes["x"].Value), float.Parse(scaleXmlNode.Attributes["y"].Value), float.Parse(scaleXmlNode.Attributes["z"].Value)); GameObject parentObj = GameObject.Find(parentName); if (parentObj) { gameObject.transform.parent = parentObj.transform; TextMesh mesh = gameObject.AddComponent<TextMesh>(); if (mesh != null) { mesh.text = gameObject.name; } gameObject.name = objectGuid; } } } beginLoad = true; } IEnumerator DownLoadText() { WWW www = new WWW(bundlesUrl); yield return www; string testurl = www.text; Dictionary<string, string> dic = www.responseHeaders; Debug.Log("testurl = " + testurl + "end"); string[] sArr = testurl.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < sArr.Length; i++) { //Debug.LogFormat("sArr[{0}] = {1}", i, sArr[i]); urlQueue.Enqueue(sArr[i]); } IsLoad = true; if (www != null) { www.Dispose(); www = null; } } }
每個場景資源都放一個單獨的目錄,所以需要兩個公有變數來記錄不同場景的連結資訊,在保留場景中做好配置即可。專案製作中做了特效,在資源未下載完成時可以用一個動畫代替,等正真的資源下載成功並顯示後將動畫刪除。如果不需要可以不做位置節點的顯示和刪除。