美文网首页unity
安卓动态加载StreamingAssets路径下的资源

安卓动态加载StreamingAssets路径下的资源

作者: S_H_C | 来源:发表于2017-07-17 16:52 被阅读0次

    最近负责把一个低模的HTC VR项目打包到一体机,一体机其实就可以看成一个安卓机,遇到的问题就是原来项目打包到安卓后跑步起来,网上查找资料才知道是因为StreamingAssets路径下的资源加载路径不同,安卓和pc平台的加载路径不一样,可以参考http://zhaolongchn.blog.163.com/blog/static/1906585042013624115926451/
    得出结论,在安卓平台StreamingAssets文件下的资源加载必须通过www的方式异步加载,而且要注意加载路径。下面通过一个小demo来测试一下:

    首先搭建一个场景

    Paste_Image.png

    然后在StreamingAssets文件下创建一个xml文件

    Paste_Image.png
    <?xml version="1.0" encoding="utf-8"?>
    <npcData>
      <value>
        <ID>2017</ID>
        <Name>LuNa</Name>
        <Sex>woman</Sex>
      </value>
      
    
    </npcData>
    

    切记必须是utf-8的格式。该xml文件就用来后续我们用来测试资源加载,把xml文件当成资源,就不再实例出怪物之类的物体了。

    创建储存xml文件数据信息的脚本

    Paste_Image.png
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    public class XmlData  {
        public int id_;
        public int mID
        {
            get { return id_; }
            set { id_ = value; }
        }
    
        public string name_;
        public string mName
        {
            get { return name_; }
            set { name_ = value; }
        }
    
        public string sex_;
        public string mSex
        {
            get { return sex_; }
            set { sex_ = value; }
        }
    }
    
    

    创建一个解析xml文件的脚本类

    Paste_Image.png
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Xml;
    using System.IO;
    
    public class JXXml
    {
    
        public static XmlData ReadXML(string xmlfile)//读取xml信息
        {
            XmlData npcdata = new XmlData();
            if (xmlfile != string.Empty)
            {
                //去除utf-8格式的bom,这样才能读取xml内容
                StringReader stringReader = new StringReader(xmlfile);
                stringReader.Read(); // skip BOM
                string result = stringReader.ReadToEnd();
                stringReader.Close();
    
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(result);
                XmlNode npcNode = xmlDoc.DocumentElement;
                foreach (XmlNode npcSonNode in npcNode.ChildNodes)
                {
                    if (npcSonNode.Name == "value")
                    {
                        npcdata.mID = int.Parse(npcSonNode.ChildNodes.Item(0).InnerText);
                        npcdata.mName = npcSonNode.ChildNodes.Item(1).InnerText;
                        npcdata.mSex = npcSonNode.ChildNodes.Item(2).InnerText;
                    }
                }
            }
                return npcdata;
            
        }
    }
    

    最后创建一个脚本触发加载

    Paste_Image.png
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class LoadXmlTest : MonoBehaviour {
        private TextMesh textmesh;
        private string path;
        private string result;
    
        void Start () {
            textmesh = GetComponent<TextMesh>();
            path = Application.streamingAssetsPath + "/TestXml.xml";
            StartCoroutine(LoadXml());
        }
        
    
        void Update () {
            
        }
    
        private void OnGUI()
        {
            GUIStyle titleStyle = new GUIStyle();
            titleStyle.fontSize = 40;
            titleStyle.normal.textColor = new Color(46f / 256f, 163f / 256f, 256f / 256f, 256f / 256f);
            GUI.Label(new Rect(100, 40, 500, 200),result, titleStyle);
        }
    
        IEnumerator  LoadXml()
        {
            WWW www = new WWW("file://" + Application.streamingAssetsPath+ "/TestXml.xml");
            yield return www;
            textmesh.text = www.text;
            
            XmlData npcdata = JXXml.ReadXML(www.text);
            result = npcdata.name_; 
        }
    }
    

    在unity运行!!!注意是在unity,不是打包后在安卓平台

    Paste_Image.png

    看到game视图我们就能确定我们已经成功的用www实现了StreamingAssets路径下的资源加载,但是需要注意,我们此时是在unity里面运行的,如果我们要打包到安卓,就需要改一下加载路径,改成:

    WWW www = new WWW( Application.streamingAssetsPath+ "/TestXml.xml");
    

    也就是把"file://" +去掉了。此时打包到安卓就可以运行出正确结果了。

    总结

    1、安卓读取StreamingAssets路径下的文件不能用DirectoryInfo类(切记!!!),只能通过www异步加载,然后就是注意各个平台的访问路径不一样;
    2、读取xml文件时遇到的坑,就是如果把解析xml代码改成:

    public static XmlData ReadXML(string xmlfile)//读取xml信息
        {
            XmlData npcdata = new XmlData();
            if (xmlfile != string.Empty)
            {
                //去除utf-8格式的bom,这样才能读取xml内容
                //StringReader stringReader = new StringReader(xmlfile);
                //stringReader.Read(); // skip BOM
                //string result = stringReader.ReadToEnd();
                //stringReader.Close();
    
                XmlDocument xmlDoc = new XmlDocument();
    
                xmlDoc.LoadXml(xmlfile);   //注释的时候记得把参数改成传入的参数
    
                XmlNode npcNode = xmlDoc.DocumentElement;
                foreach (XmlNode npcSonNode in npcNode.ChildNodes)
                {
                    if (npcSonNode.Name == "value")
                    {
                        npcdata.mID = int.Parse(npcSonNode.ChildNodes.Item(0).InnerText);
                        npcdata.mName = npcSonNode.ChildNodes.Item(1).InnerText;
                        npcdata.mSex = npcSonNode.ChildNodes.Item(2).InnerText;
                    }
                }
            }
                return npcdata;
            
        }
    

    这样再运行就会报错:

    Paste_Image.png

    出现这个错误的原因是因为Unity3D加载XML文件的时候,XML文件必须保存为UTF-8编码的格式,同时还必须去掉开头的两个字节(BOM)用来标识UTF-8用的。如何去掉bom标示就用刚才注释掉的代码就行了,分享链接http://answers.unity3d.com/questions/10904/xmlexception-text-node-canot-appear-in-this-state.html

    去掉bom标示后就可以正常解析了,很神奇,明明前后打印出来字符串都一样。

    相关文章

      网友评论

        本文标题:安卓动态加载StreamingAssets路径下的资源

        本文链接:https://www.haomeiwen.com/subject/uxsfkxtx.html