unity3d 获取文件_unity3d 读取文件 - CSDN
  • unity文件存储和读取

    2016-12-09 12:59:47
    前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖,总结成一套相同问题的解决方案供各位同行拍砖探讨。眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动...

    原文地址:http://www.cnblogs.com/murongxiaopifu/p/4199541.html

    前言:

    一直有个想法,就是把工作中遇到的坑通过自己的深挖,总结成一套相同问题的解决方案供各位同行拍砖探讨。眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大脑和手指了。那么今天开始,小匹夫会记录一些平时工作中遇到的坑,以及小匹夫的应对方法,欢迎各位拍砖讨论。那么今天主要讨论一下Unity3D在移动端如何动态的读取外部文件,比如csv(txt),xml一类的文件。主要涉及的问题,就是PC端上本来测试的好好的东西,到了移动端就不能用了,所以要讨论一下PC端和移动端的区别,那么下一个问题自然而然的就是移动端的资源路径(要讨论一下ResourcesStreamingAssetsAssetBundlePersistentDataPath),最后一步就是找到了资源如何读取(这里也会具体到对应的几种情况,即ResourcesStreamingAssetsAssetBundle),主要的思路就是这样啦。对嘞,前言部分还是要祝各位看官新的一年身体健康,升职加薪。

    假如我想在editor里动态读取文件

    实际的游戏开发中,其实有相当一部分静态数据是可以放在客户端的,所以势必会产生要动态读取这些文件的需求,比如csv(其实就是文本文件),xml等等。我相信大家不管是用win还是用mac来做unity3d的开发,都一定要先在editor中去实现基本的功能,在具体到各个移动平台上去调试。所以作为要读取外部文件的第一步,显然我们要先在editor也就是pc上实现这个功能。

    下面给各位举一个读取xml的例子,也是我在以前的一篇文章《自己动手之使用反射和泛型,动态读取XML创建类实例并赋值》中使用过的,动态读取一个xml文件并动态生成一个类。

    下面是我们用来做例子的xml文件,Test.xml:

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <test>
        <name>chenjd</name>
        <blog>http://www.cnblogs.com/murongxiaopifu/</blog>
        <organization>Fanyoy</organization>
        <age>25</age>
    </test>
    复制代码

     

    我们就可以很任性的把这个文件随便丢在一个地方,只要你能指定对它的地址。例如我还把它放在那篇文章中的地址Assets/xml-to-egg/xml-to-egg-test/文件夹下(的确很任性)

     下面我们实现在PC上读取这个文件内容的代码:

    复制代码
    //读取xml测试
    using UnityEngine;
    using System.Collections;
    using EggToolkit;
    using System.Xml.Linq;
    public class Test : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
            XElement result = LoadXML("Assets/xml-to-egg/xml-to-egg-test/Test.xml");//任性的地址
            Debug.Log(result.ToString());
        }
        
        // Update is called once per frame
        void Update () {
        
        }
    
        private  XElement LoadXML(string path)
        {
            XElement xml = XElement.Load(path);
            return xml;
        }
    }
    复制代码

    结果如下:

    结果是读取成功了。但是你以为到这一步就成功了,那就错了。因为这样的代码到移动端是行不通的,至少2处可以被骂sb:

    1. 醉人的地址,地址参数那样写就不用考虑跨平台了。所以这个sb点引出的问题就是在移动端unity3d找不到目标文件
    2. 使用的还是pc上传统的一套读取资源的做法,没有使用unity3d提供的方法,所以可能导致的问题是找得到文件但是没有正确的读取文件内容

    以上用红色标出的问题,便是小匹夫想到的可能出现的问题,也是下文要讨论的内容。那么我们首先来看看资源路径在各个平台上的不同之处吧。

    移动平台的资源路径问题

    想要读取一个文件,自然首先要找到这个文件,下面小匹夫首先会总结一下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中各个地址在不同平台上的含义,下一个问题就来了,也就是我打包之后的资源要怎么和这些地址对应上呢?要知道在pc的editor里默认的资源文件存放的路径就是Assets啊,为何又会派生出那么多路径呢?那么就带着这个疑问,和小匹夫一起进行下文的内容吧。

    简单介绍一下unity3d中资源的处理种类(欢迎拍砖):

    小匹夫遇到过的大体就是如下几种了,Resources、StreamingAssets、AssetBundle、PersistentDataPath,下面简单分析一下。

    Resources:

    是作为一个Unity3D的保留文件夹出现的,也就是如果你新建的文件夹的名字叫Resources,那么里面的内容在打包时都会被无条件的打到发布包中。它的特点简单总结一下就是:

    1. 只读,即不能动态修改。所以想要动态更新的资源不要放在这里。
    2. 会将文件夹内的资源打包集成到.asset文件里面。因此建议可以放一些Prefab,因为Prefab在打包时会自动过滤掉不需要的资源,有利于减小资源包的大小。
    3. 主线程加载。
    4. 资源读取使用Resources.Load()。

    StreamingAssets:

    要说到StreamingAssets,其实和Resources还是蛮像的。同样作为一个只读的Unity3D的保留文件夹出现。不过两者也有很大的区别,那就是Resources文件夹中的内容在打包时会被压缩和加密。而StreamingAsset文件夹中的内容则会原封不动的打入包中,因此StreamingAssets主要用来存放一些二进制文件。下面也同样做一个简单的总结:

    1. 同样,只读不可写。
    2. 主要用来存放二进制文件。
    3. 只能用过WWW类来读取。

    AssetBundle:

    关于AssetBundle的介绍已经有很多了。简而言之就是把prefab或者二进制文件封装成AssetBundle文件(也是一种二进制)。但是也有硬伤,就是在移动端无法更新脚本。下面简单的总结下:

    1. 是Unity3D定义的一种二进制类型。
    2. 最好将prefab封装成AseetBundle,不过上面不是才说了在移动端无法更新脚本吗?那从Assetbundle中拿到的Prefab上挂的脚本是不是就无法运行了?也不一定,只要这个prefab上挂的是本地脚本,就可以。
    3. 使用WWW类来下载。

    PersistentDataPath:

    看上去它只是个路径呀,可为什么要把它从路径里面单独拿出来介绍呢?因为它的确蛮特殊的,这个路径下是可读写。而且在iOS上就是应用程序的沙盒,但是在Android可以是程序的沙盒,也可以是sdcard。并且在Android打包的时候,ProjectSetting页面有一个选项Write Access,可以设置它的路径是沙盒还是sdcard。下面同样简单的总结一下:

    1. 内容可读写,不过只能运行时才能写入或者读取。提前将数据存入这个路径是不可行的。
    2. 无内容限制。你可以从StreamingAsset中读取二进制文件或者从AssetBundle读取文件来写入PersistentDataPath中。
    3. 写下的文件,可以在电脑上查看。同样也可以清掉。

    好啦,小匹夫介绍到这里,各位看官们是不是也都清楚了一些呢?那么下面我们就开始最后一步了,也就是如何在移动平台如何读取外部文件。

    移动平台读取外部文件的方法

    上文小匹夫之所以要介绍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。

    下面上图好啦:

     

    这样,我们就实现了几种动态读取外部文件的操作。各位看官是否看明白了呢?当然文章仓促,还有很多不足,欢迎大家拍砖探讨~


    展开全文
  • Unity3D文件读写文件

    2015-07-23 01:50:06
    开始正文,为了完成上述功能,自己本地做了很多实验,为了统一资源版本,我想到的办法就是把所有的AssetsBundle文件都保存到unity的沙盒目录下,即Application.persistentDataPath这个目录下。从Str

    为了完成资源的读取和保存,这里做了好多的实验,也参考了很多的文章和帖子,这里十分感谢雨松的网站,很多时候都能在那里找到思路和相应的回答。希望这个网站能一直办下去。

    开始正文,为了完成上述功能,自己本地做了很多实验,为了统一资源版本,我想到的办法就是把所有的AssetsBundle文件都保存到unity的沙盒目录下,即Application.persistentDataPath这个目录下。从StreamingAssetsPath目录将文件拷贝出来就成了一个问题,由于StreamingAssetsPath这个的只读属性,能使用的办法只有一个,用www把目录中的2进制文件先加载进来,再把获取到的资源使用Stream的方式将文件写到persistentDataPath目录下。用了两天,查阅了大量的文章及回复,揪掉了好多头发才把这个问题搞定。这里只写具体遇到的问题,代码的话就不方便上传了。

    几个点需要注意到:

    1、从StreamingAssetsPath读取的时候只能使用WWW的方式,这就限定了读取时只能使用协同方法(4.5.2以下版本,这个版本号以上的unity暂时没有研究过)。

    2、在Android真机上读取的时候需要注意读取文件的路径,网上有很多解释,这里就不写了。

    3、写文件的时候千万不要把写文件的操作也放到WWW读取的协同方法里。否则很容易写文件的操作会执行的不成功,虽然不报错,文件也能创建,但是文件是空的。

    以上就是这两天的深刻体会。因为要做成管理器,所以这部分代码写的很痛苦,逻辑组织起来也比较讨厌,尤其在真机上测试的时候简直就是灾难。

    还有个建议。一定要事先写一个简单的日志输出类,可以用网上的输出到屏幕的插件,但是那个插件的缺点就是回溯过程的时候会稍微费劲点。而且不利于保护逻辑有bug时的现场记录。

    展开全文
  • 教我们初步的破解unity3d资源的基本方法 附上原帖的链接: http://www.xuanyusong.com/archives/2584 下面我会从头介绍一下提取的全过程: 步骤一:首先从 https://github.com/ata4/disunity/releases ...

    首先感谢 雨松MOMO 的一篇帖子 教我们怎么提取 .ipa 中的游戏资源。教我们初步的破解unity3d资源的基本方法
    附上原帖的链接:
    http://www.xuanyusong.com/archives/2584

    下面我会从头介绍一下提取的全过程:

    步骤一:首先 https://github.com/ata4/disunity/releases 下载 DisUnity v0.3.1
    也可以直接用工具下载 https://github.com/ata4/disunity/releases/download/v0.3.1/disunity_v0.3.1.zip
    我解压到了D:\disunity_v0.3.1 这个路径 大家根据自己的需求来选择自己的路径吧

    步骤二:确保安装了 Java JDK 7
    下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
    检测是否安装成功 在cmd输入 java -version 可以打印出版本号 说明应该没问题了。如果没有成功这里就不详细介绍了 问下度娘或者google一下(虽然最近google有些杯具了),请大家见谅。

    步骤三:获取可以破解的源文件 首先我们需要Android的 .apk 或者 IOS的 .ipa  或者网页游戏的.unity3d  和 .boundle 文件
    Android:  先看看 Android 的 apk 安装包吧,把下好的文件后缀名.apk 直接改成 .rar 解压到单独的文件夹  可以反编译的文件的路径就在:解压后的文件夹\assets\bin\Data
    IOS: ios的 ipa的安装包 也是同样的原理 把.ipa 改成 .rar 然后解压到单独的文件夹 可以反编译的文件的路径就在: 解压后的文件夹\Payload\godoflight.app\Data  (这里我用的是神之光举例子 所以是 godoflight.app)
    网页:  这个我们重点讲一下

    下面我讲一下如何提取unity3d做的网页游戏的资源

    首先我们先要下载 火狐浏览器 http://www.firefox.com.cn/ 这是官方网站 请大家自行下载吧。

    然后安装 FireBug 插件 上图了

    然后搜索 Firebug 找到后点安装

    安装成功后这里会有个虫子的图标

    准备工作完成了,下面我们找一个unity3d开发的网页游戏 这里我们用 《冰火破坏神》 来举例,算是给完美做广告了 虽然他们一定会恨我的(坏笑)。


    先登录游戏,然后打开firebug  如图 点 [网络] -> [全部] 如果目前网页中有unity的资源的话 就会在下面的列表里出现

    这里我先清理了一下因为里面有很多不是unity的资源文件 列表清空了之后 我点 【进入游戏】 就进入了一个加载界面列表里开始加载新的资源


    有.boundle 和 .unity3d 的资源 这就是我们需要的 至于其他的资源 我也是刚刚才尝试出来的估计就这两种有用的文件吧 如果不是还请大家补充 大家共同研究哈。

    这里已经加载了不少资源了 然后就是蛋疼的下载 因为一直没有很好的批量下载的方法 我目前还是一个一个的下载 如果大家有好的方法的话 希望可以分享一下 感激不尽。

    复制链接 然后我用工具下载下来就可以了(我用的QQ旋风)。

    到此需要做的准备基本完成下面我们开始反编译。

    步骤四:
      打开cmd 进入步骤一中的 D:\disunity_v0.3.1 文件夹中

    下面是disunity_v0.3.1中的目录结构

    然后我们可以用命令 disunity extract 需要反编译的文件的路径\*.* 就可以了
    我的反编译文件放在了E:\Downloads\szgPJB(jb51.net)\assets\bin\Data 这个文件夹中 用 *.* 就可以把里面的文件全部反编译 当然无法识别的文件是没法反编出来的  

    从.ipa和.apk中解压出来的资源 貌似只有 .assets 文件可以反编译出来


    从网页上下载的.boundle和.unity3d 文件也可以放到一个文件夹 用上面的方法 反编译出来。
    当然 单个文件的话 把*.* 替换成想要反编译的文件就可以了

    以上就是整个反编译的过程

    反编译出来的文件  会分几个类别  分别放到以下文件夹中

    audioclip 是音频文件
    dubemap这不太清楚 里面存放的好像是贴图文件
    font 是 字体
    mesh 是 模型文件 .obj
    shader 是 里面是.shader文件
    Texture2d 是 贴图文件

    好了 先写到这里吧 有什么错误和不合适得地方请大家 批评指正  这是我写过的最长的一篇帖子了 还请大家多多支持。 
    原文地址:http://bbs.9ria.com/thread-401140-1-1.html

    展开全文
  • Unity3D读取文件

    2017-05-20 11:48:46
    实际的游戏开发中,其实有相当一部分静态数据是可以放在客户端的,所以...我相信大家不管是用win还是用mac来做unity3d的开发,都一定要先在editor中去实现基本的功能,在具体到各个移动平台上去调试。所以作为要读取

    装载自:http://www.cnblogs.com/murongxiaopifu/p/419954

    实际的游戏开发中,其实有相当一部分静态数据是可以放在客户端的,所以势必会产生要动态读取这些文件的需求,比如csv(其实就是文本文件),xml等等。我相信大家不管是用win还是用mac来做unity3d的开发,都一定要先在editor中去实现基本的功能,在具体到各个移动平台上去调试。所以作为要读取外部文件的第一步,显然我们要先在editor也就是pc上实现这个功能。

    下面给各位举一个读取xml的例子,也是我在以前的一篇文章《自己动手之使用反射和泛型,动态读取XML创建类实例并赋值》中使用过的,动态读取一个xml文件并动态生成一个类。

    下面是我们用来做例子的xml文件,Test.xml:

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <test>
        <name>chenjd</name>
        <blog>http://www.cnblogs.com/murongxiaopifu/</blog>
        <organization>Fanyoy</organization>
        <age>25</age>
    </test>
    复制代码

     

    我们就可以很任性的把这个文件随便丢在一个地方,只要你能指定对它的地址。例如我还把它放在那篇文章中的地址Assets/xml-to-egg/xml-to-egg-test/文件夹下(的确很任性)

     下面我们实现在PC上读取这个文件内容的代码:

    复制代码
    //读取xml测试
    using UnityEngine;
    using System.Collections;
    using EggToolkit;
    using System.Xml.Linq;
    public class Test : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
            XElement result = LoadXML("Assets/xml-to-egg/xml-to-egg-test/Test.xml");//任性的地址
            Debug.Log(result.ToString());
        }
        
        // Update is called once per frame
        void Update () {
        
        }
    
        private  XElement LoadXML(string path)
        {
            XElement xml = XElement.Load(path);
            return xml;
        }
    }
    复制代码

    结果如下:

    结果是读取成功了。但是你以为到这一步就成功了,那就错了。因为这样的代码到移动端是行不通的,至少2处可以被骂sb:

    1. 醉人的地址,地址参数那样写就不用考虑跨平台了。所以这个sb点引出的问题就是在移动端unity3d找不到目标文件
    2. 使用的还是pc上传统的一套读取资源的做法,没有使用unity3d提供的方法,所以可能导致的问题是找得到文件但是没有正确的读取文件内容

    以上用红色标出的问题,便是小匹夫想到的可能出现的问题,也是下文要讨论的内容。那么我们首先来看看资源路径在各个平台上的不同之处吧。

    移动平台的资源路径问题

    想要读取一个文件,自然首先要找到这个文件,下面小匹夫首先会总结一下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中各个地址在不同平台上的含义,下一个问题就来了,也就是我打包之后的资源要怎么和这些地址对应上呢?要知道在pc的editor里默认的资源文件存放的路径就是Assets啊,为何又会派生出那么多路径呢?那么就带着这个疑问,和小匹夫一起进行下文的内容吧。

    简单介绍一下unity3d中资源的处理种类(欢迎拍砖):

    小匹夫遇到过的大体就是如下几种了,Resources、StreamingAssets、AssetBundle、PersistentDataPath,下面简单分析一下。

    Resources:

    是作为一个Unity3D的保留文件夹出现的,也就是如果你新建的文件夹的名字叫Resources,那么里面的内容在打包时都会被无条件的打到发布包中。它的特点简单总结一下就是:

    1. 只读,即不能动态修改。所以想要动态更新的资源不要放在这里。
    2. 会将文件夹内的资源打包集成到.asset文件里面。因此建议可以放一些Prefab,因为Prefab在打包时会自动过滤掉不需要的资源,有利于减小资源包的大小。
    3. 主线程加载。
    4. 资源读取使用Resources.Load()。

    StreamingAssets:

    要说到StreamingAssets,其实和Resources还是蛮像的。同样作为一个只读的Unity3D的保留文件夹出现。不过两者也有很大的区别,那就是Resources文件夹中的内容在打包时会被压缩和加密。而StreamingAsset文件夹中的内容则会原封不动的打入包中,因此StreamingAssets主要用来存放一些二进制文件。下面也同样做一个简单的总结:

    1. 同样,只读不可写。
    2. 主要用来存放二进制文件。
    3. 只能用过WWW类来读取。

    AssetBundle:

    关于AssetBundle的介绍已经有很多了。简而言之就是把prefab或者二进制文件封装成AssetBundle文件(也是一种二进制)。但是也有硬伤,就是在移动端无法更新脚本。下面简单的总结下:

    1. 是Unity3D定义的一种二进制类型。
    2. 最好将prefab封装成AseetBundle,不过上面不是才说了在移动端无法更新脚本吗?那从Assetbundle中拿到的Prefab上挂的脚本是不是就无法运行了?也不一定,只要这个prefab上挂的是本地脚本,就可以。
    3. 使用WWW类来下载。

    PersistentDataPath:

    看上去它只是个路径呀,可为什么要把它从路径里面单独拿出来介绍呢?因为它的确蛮特殊的,这个路径下是可读写。而且在IOS上就是应用程序的沙盒,但是在Android可以是程序的沙盒,也可以是sdcard。并且在Android打包的时候,ProjectSetting页面有一个选项Write Access,可以设置它的路径是沙盒还是sdcard。下面同样简单的总结一下:

    1. 内容可读写,不过只能运行时才能写入或者读取。提前将数据存入这个路径是不可行的。
    2. 无内容限制。你可以从StreamingAsset中读取二进制文件或者从AssetBundle读取文件来写入PersistentDataPath中。
    3. 写下的文件,可以在电脑上查看。同样也可以清掉。

    好啦,小匹夫介绍到这里,各位看官们是不是也都清楚了一些呢?那么下面我们就开始最后一步了,也就是如何在移动平台如何读取外部文件。

    移动平台读取外部文件的方法

    上文小匹夫之所以要介绍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。

    下面上图好啦:

     

    这样,我们就实现了几种动态读取外部文件的操作。各位看官是否看明白了呢?当然文章仓促,还有很多不足,欢迎大家拍砖探讨~

    如果各位看官觉得文章写得还好,那么就容小匹夫跪求各位给点个“推荐”,谢啦~

    装模作样的声明一下:本博文章若非特殊注明皆为原创,若需转载请保留原文链接及作者信息慕容小匹夫

    展开全文
  • unity 3D读取文件(excel和json),可以在unity里面读取excel和json类型的文件内容
  • Unity3D读取外部文件

    2020-03-30 17:01:18
    Unity3D读取外部文件xml、jsonC#读取XML文档C#读取Json文本 C#读取XML文档 Unity3D读取XML文档不需要另外导入程序集(dll),直接引用System.Xml就行。 C#读取XML文档的代码需要根据xml文档结构做出修改。 using ...
  • Unity3d 动态读取外部文件,1,加载封装好的内部文件。2,加载磁盘文件
  • Unity3d网络加载模型和导出unity3d格式文件
  • unity3D可视化选择文件读取选择文件路径,文件大小,模块独立,便于移植。
  • 文本文件一般是.txt文件读取和解析的方式都是非常简单的,文件编码必须是UTF-8。举个例子,通过英文逗号,来分割每一行字符串。1,张三,23,165,60 2,李四,24,167,62 3,王二,15,168,74using UnityEngine;public class...
  • unity3d读取csv文件

    2014-05-07 12:57:29
    unity3d并未提供直接读取csv文件的方法,那怎么办呢,没关系,很简单,下面看我是怎么做到的。先声明,我的操作系统是mac os。 1、创建csv文件 既然做实验嘛,没有资源怎么行,自己徒手写个csv文件吧,...
  • Unity3D文件读取

    2018-01-16 17:42:45
    是作为一个Unity3D的保留文件夹出现的,也就是如果你新建的文件夹的名字叫Resources,那么里面的内容在打包时都会被无条件的打到发布包中。它的特点简单总结一下就是: 只读,即不能动态修改。所以想要动态更新的...
  •  1、unity3d如何访问android SD卡的文件  2、如果把android端代码以jar包形式由unity3d调用 闲话不多说,现在咱们进入正题。 一、unity3d如何访问android SD卡的文件  实现效果是unity3d调用android相册或相机,...
  • Unity3d读写文件操作

    2019-01-22 19:33:49
    Unity3d读写文件操作
  • 在mac os下写过手游程序的应该都清楚csv文件,它类似于excel...unity3d并未提供直接读取csv文件的方法,所以要我们人工处理一下,很简单,像上一篇文章一样,粗暴的把csv的扩展名改成txt吧,谁让unity3d比较亲txt呢。
  • Unity3D 读取XML文件里面的属性using System.Collections; using System.Collections.Generic; using System.IO; using System.Xml; using UnityEngine;public class ReadXML : MonoBehaviour { // Use this for ...
  • Unity3D地形文件

    2020-07-30 23:30:32
    Unity3D 地形
  • 创建一个MyFile.txt文件、将它放到streamingAssetsPath文件夹下(没有的话手动创建一个)  var fileAddress = System.IO.Path.Combine(Application.streamingAssetsPath, "MyFile.txt"); FileInfo fInfo0 = new ...
  • unity读取txt文件 方法1: 1 using UnityEngine; 2 using System.Collections; 3 using UnityEngine.UI; 4 public class GetTxT : MonoBehaviour { 5 6 public Text texts; 7 void Start () { ....
  • Unity3d 动态读取外部文件 收藏 分两种情况: 1,加载封装好的内部文件。 var aaa : Material;//空材质 var bbb : GameObject;//要绑定材质的模型 function Start() { aaa.mainTexture = Resources....
1 2 3 4 5 ... 20
收藏数 13,509
精华内容 5,403
关键字:

unity3d 获取文件