unity

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

2017-07-17  本文已影响0人  S_H_C

最近负责把一个低模的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标示后就可以正常解析了,很神奇,明明前后打印出来字符串都一样。

上一篇下一篇

猜你喜欢

热点阅读