安卓动态加载StreamingAssets路径下的资源
最近负责把一个低模的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.pngusing 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.pngusing 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.pngusing 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标示后就可以正常解析了,很神奇,明明前后打印出来字符串都一样。