---
title: "资源路径与文件加载"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/unity-asset-path-file-loading/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/05-游戏图形与运行时/Unity/资源路径与文件加载.md"
content_hash: f05d7a9d3d7720d04d4338f231fd0541089120d0fd1cf54e33668ddb5a1832dd
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# 资源路径与文件加载

> 创建时间：2020/8/20 20:08

  * 资源路径与文件加载
    * 特殊文件夹
      * Editor
      * Editor Default Resources
      * Resources
        * Resource.Load()
        * Resources.LoadAssetAtPath()
        * AssetDatabase.LoadAssetAtPath()
      * StreamingAssets
      * Application.persistentDataPath
      * Plugins
      * Gizmos
    * PC上读取文件
      * 读取XML文件并生成一个类
    * 移动平台的资源路径
      * Application.streamingAssetsPath
    * Ref

路径相关的测试：
<https://zhuanlan.zhihu.com/p/58710435>
<https://github.com/Zhunity/UnityPractice/blob/master/Assets/PathTest/PathTest.cs>

## 特殊文件夹

### Editor

可以在根目录下，也可以在子目录里，只要名子叫Editor就可以。
Editor下面放的所有资源文件或者脚本文件都不会被打进发布包中，并且脚本也只能在编辑时使用。一般呢会把一些工具类的脚本放在这里，或者是一些编辑时用的DLL。

### Editor Default Resources

中间是有空格的，必须放在Project视图的根目录下，如果你想放在/xxx/xxx/Editor Default Resources 这样是不行的。
把编辑器用到的一些资源放在这里，比如图片、文本文件、等等。它和Editor文件夹一样都不会被打到最终发布包里，仅仅用于开发时使用。你可以直接通过EditorGUIUtility.Load去读取该文件夹下的资源。

### Resources

可以在根目录下，也可以在子目录里，只要名子叫Resources就可以。比如目录：/xxx/xxx/Resources 和 /Resources 是一样的，无论多少个叫Resources的文件夹都可以。Resources文件夹下的资源 **不管你用还是不用都会被打包进.apk或者.ipa**

> 一下建议：
>  强烈不建议使用Resources系统，原因如下：
>
>   * 使用Resources文件夹将会使细粒度的内存管理变得更难
>
>   * 对Resources文件夹的不恰当使用会导致应用程序构架和启动时间变长
>
>   * 随着Resources文件夹数量的增加，在这些文件夹中管理Asset将会变得越来越难
>
>   * 使用Resources系统会降低项目向不同平台提供定制内容的能立，并且导致项目无法进行增量内容更新
>
>   * AssetBundle变体是Unity用来在设备层面调整内容的首选工具。
>
>

>
> 哪些情况下Resources系统很有用？
>
>   * Resources系统简单易用的特点使其非常适合用于快速开发原型。不过，当项目进入正式开发阶段时，应该停止使用Resources文件夹。
>
>   * Resources文件夹可以用于处理一些简单的内容：
>
>   * 在项目的整个生命周期中都被使用的内容
>
>   * 非内存密集型内容
>
>   * 不太可能添加补丁或者不受平台和设备影响的内容
>
>   * 用于最小化引导的内容
>
>

#### Resource.Load()

编辑时和运行时都可以通过Resource.Load来直接读取。

#### Resources.LoadAssetAtPath()

它可以读取Assets目录下的任意文件夹下的资源，它可以在 **编辑时或者编辑器运行时用** ，它但是它 **不能在真机上用** ，它的路径是 **“Assets/xx/xx.xxx”** 必须是这种路径，并且 **要带文件的后缀名** 。

#### AssetDatabase.LoadAssetAtPath()

它可以读取Assets目录下的任意文件夹下的资源，它 **只能在编辑时用** 。它的路径是” **Assets/xx/xx.xxx** ” 必须是这种路径，并且 **要带文件的后缀名** 。

我觉得在电脑上开发的时候尽量来用Resource.Load() 或者 Resources.LoadAssetAtPath() ，假如手机上选择一部分资源要打assetbundle，一部分资源Resource.Load().那么在做.apk或者.ipa的时候 现在都是用脚本来自动化打包，在打包之前 可以用AssetDatabase.MoveAsset()把已经打包成assetbundle的原始文件从Resources文件夹下移动出去在打包，这样打出来的运行包就不会包行多余的文件了。打完包以后再把移动出去的文件夹移动回来。

### StreamingAssets

这个文件夹下的资源也会全都打包在.apk或者.ipa 它和Resources的区别是， **Resources会压缩文件** ，但是 **它不会压缩** 原封不动的打包进去。并且它是一个 **只读** 的文件夹，就是程序运行时只能读 不能写。它在各个平台下的路径是不同的，不过你可以用Application.streamingAssetsPath 它会根据当前的平台选择对应的路径。

一般把预制的二进制文件放在里面。

有些游戏为了让所有的资源全部使用assetbundle，会把一些初始的assetbundle放在StreamingAssets目录下，运行程序的时候在把这些assetbundle拷贝在Application.persistentDataPath目录下，如果这些assetbundle有更新的话，那么下载到新的assetbundle在把Application.persistentDataPath目录下原有的覆盖掉。

### Application.persistentDataPath

可读可写。可以是程序的沙盒，也可以是SD Card
在打包Android的时候，ProjectSetting页面有个选项: WriteAccess，可以设置他的路径是沙盒还是SD Card。
Android上如果保存在沙盒中，需要root才能取出文件。

只有运行时才能在这个路径下写文件。如果要写android交互插件，.java类中是无法访问Unity中的资源的。那么，把资源放在Resources文件夹，在比如Awake函数中把二进制文件copy到persistentDataPath下面，这样C# java两边就都可以访问他了。

```csharp
class Program
{
    static void Main(string[] args)
    {
        dynamic dyn = 1;
        object obj = 1;
        dyn = dyn + 3;
        //obj = obj + 3; 报错

        // Rest the mouse pointer over dyn and obj to see their
        // types at compile time.
        System.Console.WriteLine(dyn.GetType());
        System.Console.WriteLine(obj.GetType());
    }
}

```

### Plugins

如果做手机游戏开发一般 andoird 或者 ios 要接一些sdk 可以把sdk依赖的库文件放在这里，比如 .so .jar .a 文件。这样打完包以后就会自动把这些文件打在你的包中。

### Gizmos

可以在Scene视图里给某个坐标绘制一个icon。

```csharp
class Program
{
    static void Main(string[] args)
    {
        dynamic dyn = 1;
        object obj = 1;
        dyn = dyn + 3;
        //obj = obj + 3; 报错

        // Rest the mouse pointer over dyn and obj to see their
        // types at compile time.
        System.Console.WriteLine(dyn.GetType());
        System.Console.WriteLine(obj.GetType());
    }
}

```

OnDrawGizmos()方法:
比如要做摄像机轨迹，那么肯定是要在Scene视图中做一个预览的线，那么用Gizmos.DrawLine 和Gizmos.DrawFrustum就再好不过了。

## PC上读取文件

Application.dataPath路径在PC上：无论是Editor还是运行时都毫无压力非常万能(但在手机上无用)

### 读取XML文件并生成一个类

```csharp
class Program
{
    static void Main(string[] args)
    {
        dynamic dyn = 1;
        object obj = 1;
        dyn = dyn + 3;
        //obj = obj + 3; 报错

        // Rest the mouse pointer over dyn and obj to see their
        // types at compile time.
        System.Console.WriteLine(dyn.GetType());
        System.Console.WriteLine(obj.GetType());
    }
}

```
```csharp
class Program
{
    static void Main(string[] args)
    {
        dynamic dyn = 1;
        object obj = 1;
        dyn = dyn + 3;
        //obj = obj + 3; 报错

        // Rest the mouse pointer over dyn and obj to see their
        // types at compile time.
        System.Console.WriteLine(dyn.GetType());
        System.Console.WriteLine(obj.GetType());
    }
}

```

## 移动平台的资源路径

### Application.streamingAssetsPath

只读路径。

在Unity的Assets/目录下创建名为StreamingAssets文件夹即可。

Application.dataPath: 程序的数据文件所在文件夹。在Editor中就是Assets
安卓: /data/app/xxx.xxx.xxx.apk
iOS: Application/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data

Application.streamingAssetsPath: 流数据的缓存目录，为相对路径，适合设置一些外部数据文件
安卓: jar:file:///data/app/xxx.xxx.xxx.apk/!/assets
iOS: Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw

Application.persistentDataPath: 持久化数据存储目录的路径，可用于存储一些持久化的数据文件
安卓: /data/data/xxx.xxx.xxx/files
iOS: Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents

Application.temporaryCachePath: 临时数据的缓存目录
安卓: /data/data/xxx.xxx.xxx/cache
iOS: Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches

dataPath和streamingAssetsPath一般是相对程序的安装目录位置
persistentDataPath和temporaryCachePath一般是与系统有关的固定位置

## Ref

<https://www.cnblogs.com/FudgeBear/p/10513784.html>
<https://www.xuanyusong.com/archives/4033>
<http://www.xuanyusong.com/archives/2656>
<https://www.xuanyusong.com/archives/3229>
