关键词:
转载自:http://blog.csdn.net/u014735301/article/details/43481727
移动平台的资源路径问题
想要读取一个文件,自然首先要找到这个文件,下面小匹夫首先会总结一下unity3d中存在的各个地址,之后再总结一下各个地址在各个移动平台中的对应位置。
Unity3D中的资源路径
Application.dataPath | 此属性用于返回程序的数据文件所在文件夹的路径。例如在Editor中就是Assets了。 |
Application.streamingAssetsPath | 此属性用于返回流数据的缓存目录,返回路径为相对路径,适合设置一些外部数据文件的路径。 |
Application.persistentDataPath | 此属性用于返回一个持久化数据存储目录的路径,可以在此路径下存储一些持久化的数据文件。 |
Application.temporaryCachePath | 此属性用于返回一个临时数据的缓存目录。 |
android平台
Application.dataPath | /data/app/xxx.xxx.xxx.apk |
Application.streamingAssetsPath | jar:file:///data/app/xxx.xxx.xxx.apk/!/assets |
Application.persistentDataPath | /data/data/xxx.xxx.xxx/files |
Application.temporaryCachePath | /data/data/xxx.xxx.xxx/cache |
IOS平台
Application.dataPath | Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data |
Application.streamingAssetsPath | Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw |
Application.persistentDataPath | Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents |
Application.temporaryCachePath | Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches |
上面的3张表格,我们可以看到 dataPath和streamingAssetsPath的路径位置一般是相对程序的安装目录位置,而persistentDataPath和temporaryCachePath的路径位置一般是相对所在系统的固定位置。
简单介绍一下unity3d中资源的处理种类(欢迎拍砖):
小匹夫遇到过的大体就是如下几种了,Resources、StreamingAssets、AssetBundle、PersistentDataPath,下面简单分析一下。
Resources:
是作为一个Unity3D的保留文件夹出现的,也就是如果你新建的文件夹的名字叫Resources,那么里面的内容在打包时都会被无条件的打到发布包中。它的特点简单总结一下就是:
- 只读,即不能动态修改。所以想要动态更新的资源不要放在这里。
- 会将文件夹内的资源打包集成到.asset文件里面。因此建议可以放一些Prefab,因为Prefab在打包时会自动过滤掉不需要的资源,有利于减小资源包的大小。
- 主线程加载。
- 资源读取使用Resources.Load()。
StreamingAssets:
要说到StreamingAssets,其实和Resources还是蛮像的。同样作为一个只读的Unity3D的保留文件夹出现。不过两者也有很大的区别,那就是Resources文件夹中的内容在打包时会被压缩和加密。而StreamingAsset文件夹中的内容则会原封不动的打入包中,因此StreamingAssets主要用来存放一些二进制文件。下面也同样做一个简单的总结:
- 同样,只读不可写。
- 主要用来存放二进制文件。
- 只能用过WWW类来读取。
AssetBundle:
关于AssetBundle的介绍已经有很多了。简而言之就是把prefab或者二进制文件封装成AssetBundle文件(也是一种二进制)。但是也有硬伤,就是在移动端无法更新脚本。下面简单的总结下:
- 是Unity3D定义的一种二进制类型。
- 最好将prefab封装成AseetBundle,不过上面不是才说了在移动端无法更新脚本吗?那从Assetbundle中拿到的Prefab上挂的脚本是不是就无法运行了?也不一定,只要这个prefab上挂的是本地脚本,就可以。
- 使用WWW类来下载。
PersistentDataPath:
看上去它只是个路径呀,可为什么要把它从路径里面单独拿出来介绍呢?因为它的确蛮特殊的,这个路径下是可读写。而且在IOS上就是应用程序的沙盒,但是在Android可以是程序的沙盒,也可以是sdcard。并且在Android打包的时候,ProjectSetting页面有一个选项Write Access,可以设置它的路径是沙盒还是sdcard。下面同样简单的总结一下:
- 内容可读写,不过只能运行时才能写入或者读取。提前将数据存入这个路径是不可行的。
- 无内容限制。你可以从StreamingAsset中读取二进制文件或者从AssetBundle读取文件来写入PersistentDataPath中。
- 写下的文件,可以在电脑上查看。同样也可以清掉。
好啦,小匹夫介绍到这里,各位看官们是不是也都清楚了一些呢?那么下面我们就开始最后一步了,也就是如何在移动平台如何读取外部文件。
移动平台读取外部文件的方法
上文小匹夫之所以要介绍Resources、StreamingAssets、AssetBundle、PersistentDataPath这四个东东,就是因为读取外部资源的操作所涉及到的东西无外乎这几种。既然是用Unity3D来开发游戏,那么自然要使用Unity3D规定的操作方式,而不是我们在PC上很原始的那种操作方式来操作咯。否则就会像本文一开始所演示的那样,写出移动端无法使用的很傻的代码来。
下面小匹夫就分别实现一下利用Resources、StreamingAssets、AssetBundle来读取的过程。
Resources:
首先我们新建一个Resources目录,并且将上面我们用到的Test.xml复制一份到这个文件夹中。如图:
然后我们通过Resources的读取方法来读取Test.xml的内容。并且调用GUI将xml的内容绘制出来。
//用Resources读取xml using UnityEngine; using System.Collections; using EggToolkit; using System.Xml.Linq; using System.Xml; public class Test : MonoBehaviour { private string _result; // Use this for initialization void Start () { LoadXML("Test"); } // Update is called once per frame void Update () { } private void LoadXML(string path) { _result = Resources.Load(path).ToString(); XmlDocument doc = new XmlDocument(); doc.LoadXml(_result); } void OnGUI() { GUIStyle titleStyle = new GUIStyle(); titleStyle.fontSize = 20; titleStyle.normal.textColor = new Color(46f/256f, 163f/256f, 256f/256f, 256f/256f); GUI.Label(new Rect(400, 10, 500, 200), _result,titleStyle); } }
结果如图:
OK,Resources读取外部资源目标达成!!
下面我们继续,这次则是使用StreamingAssets来操作。
StreamingAssets:
同Resources一样,我们要新建一个StreamingAssets的文件夹来存放我们的Test.xml文件。如图:
不过前文已经说了,StreamingAssets文件夹内的东西并不会被压缩和加密,而是放进去什么就是什么,所以一般是要放二进制文件的,这里小匹夫仅仅做一个演示,各位在实际操作中切记不要直接把数据文件放到这个目录中打包。
using UnityEngine; using System.Collections; using EggToolkit; using System.Xml.Linq; using System.Xml; using System.IO; public class Test : MonoBehaviour { private string _result; // Use this for initialization void Start () { StartCoroutine(LoadXML()); } // Update is called once per frame void Update () { } /// <summary> /// 如前文所述,streamingAssets只能使用www来读取, /// 如果不是使用www来读取的同学,就不要问为啥读不到streamingAssets下的内容了。 /// 这里还可以使用persistenDataPath来保存从streamingassets那里读到内容。 /// </summary> IEnumerator LoadXML() { string sPath= Application.streamingAssetsPath + "/Test.xml"; WWW www = new WWW(sPath); yield return www; _result = www.text; } void OnGUI() { GUIStyle titleStyle = new GUIStyle(); titleStyle.fontSize = 20; titleStyle.normal.textColor = new Color(46f/256f, 163f/256f, 256f/256f, 256f/256f); GUI.Label(new Rect(400, 10, 500, 200), _result,titleStyle); } }
结果如图:
OK,StreamingAssets读取外部资源目标达成!!
下面我们继续,最后则是使用AssetBundle来操作。
AssetBundle:
来到AssetBundle,这里就和上面两个不一样了。首先我们要把我们的文件Test.xml打成AssetBundle文件,由于小匹夫使用的是小米3作为测试机,所以AssetBundle的平台选择为Andorid。
如图,我们创建了一个AssetBundle文件,并命名为TextXML。并且按照二进制文件放入StreamingAssets文件夹中的惯例,将这个AssetBundle文件放入StreamingAssets文件夹。
那么下面就是从AssetBudle中读取Test.xml的内容咯。直接上代码:
//从AssetBundle中读取xml using EggToolkit; using System.Xml.Linq; using System.Xml; using System.IO; public class Test : MonoBehaviour { private string _result; // Use this for initialization void Start () { LoadXML(); } // Update is called once per frame void Update () { } void LoadXML() { AssetBundle AssetBundleCsv = new AssetBundle(); //读取放入StreamingAssets文件夹中的bundle文件 string str = Application.streamingAssetsPath + "/" + "TestXML.bundle"; WWW www = new WWW(str); www = WWW.LoadFromCacheOrDownload(str, 0); AssetBundleCsv = www.assetBundle; string path = "Test"; TextAsset test = AssetBundleCsv.Load(path, typeof(TextAsset)) as TextAsset; _result = test.ToString(); } void OnGUI() { GUIStyle titleStyle = new GUIStyle(); titleStyle.fontSize = 20; titleStyle.normal.textColor = new Color(46f/256f, 163f/256f, 256f/256f, 256f/256f); GUI.Label(new Rect(400, 10, 500, 200), _result,titleStyle); } }
结果如图:
OK,AssetBundle读取外部资源目标也达成了!!
补充:
在此统一回答一下在评论和qq上有同学提出的一个问题:安卓上Application.persistentDataPath的内容貌似不是匹夫你表里的那个呀?在本文的评论里小匹夫已经回复过了,其实文中也说过
但是在Android可以是程序的沙盒,也可以是sdcard。并且在Android打包的时候,ProjectSetting页面有一个选项Write Access,可以设置它的路径是沙盒还是sdcard。
胡泽锐:移动开发即服务——腾讯云移动开发平台技术分享
...锐,2010年毕业加入腾讯,先后负责过QQ空间、网页应用、移动应用、移动游戏相关的工作,有着丰富的平台产品经验以及大前端开发经验,目前在腾讯云负责前端以及终端相关的工作,提出并推动移动开发平台产品的落地。很高... 查看详情
cordova插件file使用时遇到的一个平台相关的问题
...件,分享一下我在用该插件从图库读取图片时遇到的一个平台相关的小问题。使用场景,我会在APP中新增一张图片,会有一个可点击的【保存】按钮,点击时将图片copy到自己新建的目录下。在Android平台下(小米5),选中图片之... 查看详情
unity移动平台相关android打包设置
Android发布流程Unity2019及以上发布Android准备工作通过UnityHub安装Android平台相关工具1.Android构建支持2.AndroidSDK(安卓软件开发工具包)、NDKTools(本地开发工具包)3.OpenJDK(Java开发工具包)注意:Unity支持... 查看详情
移动端游戏功耗优化方法
本文给大家讲一下目前国内大多数手机厂商对移动端游戏优化的方法,主要可以分为两大类:一类是基于CPU的常规调节频率来提升游戏性能和降低游戏功耗;另一类是基于GPU相关的图形学(和计算机视觉不一样... 查看详情
如何移动相对符号链接?
】如何移动相对符号链接?【英文标题】:HowdoImovearelativesymboliclink?【发布时间】:2012-01-2107:55:19【问题描述】:我有很多相关的符号链接想要移动到另一个目录。如何在保留正确路径的同时移动符号链接(具有相对路径的链接... 查看详情
FRENDS 平台 - 如何从 foreach 循环和移动中的文件打印输出
】FRENDS平台-如何从foreach循环和移动中的文件打印输出【英文标题】:FRENDSPlattform-Howtodoaprintoutfromfilesinaforeachloopandamove【发布时间】:2021-12-1113:32:49【问题描述】:我知道如何在没有foreach循环的情况下一次移动所有项目但它是我... 查看详情
模块04
...级 os.makedirs 创建多级目录 os.sep 获取当前平台的路径分隔符 os.makedirs(os.sep.join()) 使用join拼接路径 os.mkdir() 找到路径创建一个文件夹 os.removedirs() 目录不为空时无法删除需要递归删除 ... 查看详情
移动开发平台mpaas-kylin定位(代码片段)
定位简介mPaaS提供了定位组件以方便使用定位相关服务。通过包装系统接口,该组件提供了如下功能:获取当前设备所在位置的经纬度信息的简易方法。获取经纬度信息的时间和精确度信息。支持缓存和坐标系转换。Hook... 查看详情
移动开发平台mpaas-kylin定位(代码片段)
定位简介mPaaS提供了定位组件以方便使用定位相关服务。通过包装系统接口,该组件提供了如下功能:获取当前设备所在位置的经纬度信息的简易方法。获取经纬度信息的时间和精确度信息。支持缓存和坐标系转换。Hook... 查看详情
快手大数据统一安全平台
...sp;获取大数据资讯导读本文主要介绍快手大数据统一安全平台。本文源自马玲玲老师在『快手大数据|数据中台技术交流会』上的演讲,相关视频回放可用快手APP搜索“快手大数据”观看。本文会分四个部分展开介绍。首先,对... 查看详情
advancedinstaller打包安装exe相关问题
...13.96MB软件类别:国外软件/安装制作软件语言:英文应用平台:Win2003/XP/2000/9X/基本介绍AdvancedInstaller是一款WindowsInstaller编写工具。它为创建和维护基于WindowsInstaller安装技术的安装。 查看详情
pythonos模块文件相关
...操作系统特定的路径分割符os.linesep 字符串给出当前平台使用的行终止符。例如,Windows使用‘\r\n‘,Linux使用‘\n‘而Mac使用‘\r‘。os.name 字符串指示你正在使用的平台。比如对于Windows,它是‘nt‘,而对 查看详情
终端架构深研,codeday成都站等你
CodeDay首次登陆成都,6/19,一同探讨移动端在跨平台、动态化方向下的技术选型。mPaaSCodeDay首次登陆成都成都的Coder们,大家期盼已久的CodeDay终于来了。本期CodeDay,我们召集了来自支付宝客户端工程师、前端工程师以及TW资深咨... 查看详情
linux后台开发相关面试知识点汇总脑图版
...薪资待遇。JD1:Linux服务器开发工程师20-40K职位描述负责移动游戏社区APP后台服务架构设计开发;负责移动游戏社区平台用户数据分析及相关推荐业务开发;负责移动游戏实时语音业务系统设计和开发工作。职责:负责移动游戏... 查看详情
模块(代码片段)
...path是os模块下专门用于处理路径相关的 python是一门跨平台语言,由于每个平台路径规则不同 需要一个模块来使得路径可以自动根据平台变化 path模块仅仅是对路径(字符串)进行操作不会直接操作文件importos#print(os.getcwd... 查看详情
企业该如何挑选移动平台?
在当今的移动互联时代,移动化已经成为各大企业的“标配”,但“七分选型、三分软件”,不少企业在移动化建设中,由于选型失败,走了很多弯路。那么,企业挑选移动平台时,有哪些要求呢?企业在挑选移动平台时,该注... 查看详情
如何在 Qt 中移动文件?
】如何在Qt中移动文件?【英文标题】:HowtomovefilesinQt?【发布时间】:2011-02-0621:01:55【问题描述】:Qt中是否有相当于Windows中MoveFile函数和Linux中mv命令的跨平台功能?【问题讨论】:【参考方案1】:当然,QDir::rename()遵循旧的Uni... 查看详情
错误记录visualstudio中配置ndk头文件路径(ndk的三个头文件路径|与cpu架构相关asm头文件路径选择)(代码片段)
...工具开发(VisualStudio开发AndroidNDK应用|使用Makefile构建Android平台NDK应用)博客,此处涉及到打开一个"生成文件项目";打开后,由于没有头文件依赖,无法编译;二、解决方案右键点击解决方案 查看详情