目录

  • 简述
  • 常见平台上的具体路径
  • 权限和读写
  • Unity Editor
  • Windows
  • Android
  • iOS
  • 路径注意事项
  • Application.dataPath
  • Application.streamingAssets
  • Application.persistentDataPath
  • Application.temporaryCachePath
  • 其他


简述

在Unity中,有几个特殊目录,分别如下:

  • Application.dataPath:提供对项目中Assets文件夹路径的访问,返回Assets文件夹的绝对路径
  • Application.streamingAssets:提供对项目中Assets文件夹里面的StreamingAssets文件夹路径的访问,返回的是StreamingAssets文件夹的绝对路径
  • Application.persistentDataPath:提供对持久数据路径在设备上的绝对路径的访问
  • Application.temporaryCachePath:提供对临时数据在设备上的绝对路径的访问

上述这些特殊路径,使得开发者可以更方便地在代码中对Unity资源进行更方便的管理,但是由于平台差异,导致在使用上也有很多差异,稍有不慎就会出错,因此需要对不同的平台做不同特殊处理

常见平台上的具体路径

Application.dataPath

Unity Editor

项目文件夹/Assets

Windows

项目名称_data文件夹

Android

/data/app/package name/xxx.apk

iOS

/var/containers/Bundle/Application/app sandbox/xxx.app/Data

Application.streamingAssets

Unity Editor

项目文件夹/Assets/StreamingAssets

Windows

项目名称_data文件夹/StreamingAssets

Android

jar:file:///data/app/package name/xxx.apk!/assets

iOS

/var/containers/Bundle/Application/app sandbox/xxx.app/Data/Raw

Application.persistentDataPath

Unity Editor

C:\Users\username\AppData\LocalLow\company name\product name

Windows

C:\Users\username\AppData\LocalLow\company name\product name

Android

/storage/emulated/0/Android/data/package name/files

iOS

/var/mobile/Containers/Data/Application/app sandbox/Documents

Application.temporaryCachePath

Unity Editor

C:\Users\username\AppData\Local\Temp\company name\product name

Windows

C:\Users\username\AppData\Local\Temp\company name\product name

Android

/storage/emulated/0/Android/data/package name/cache

iOS

/var/mobile/Containers/Data/Application/app sandbox/Library/Caches

权限和读写

Unity Editor

  • Application.dataPath:可读可写,以下是读txt文本示例
//使用File类读取
string filePath = Application.dataPath + "/myFile.txt";
string content = File.ReadAllText(filePath);

//使用StreamReader
string filePath = Application.dataPath + "/myFile.txt";
using (StreamReader reader = new StreamReader(filePath))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        // 对每一行进行处理
    }
}

//使用UnityWebRequest
string filePath = Application.dataPath + "/myFile.txt";
Uri uri = new Uri(filePath);  //这里使用uri可以简化很多操作,非常推荐,否则需要自己根据不同平台做处理
UnityWebRequest request = UnityWebRequest.Get(uri);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
    string content = request.downloadHandler.text;
    // 对文本内容进行处理
}
else
{
    Debug.LogError("Failed to read file: " + request.error);
}
  • Application.streamingAssets/Application.persistentDataPath/Application.temporaryCachePath:Application.dataPath一样,只需要把Application.dataPath替换成相应目录即可

Windows

  • Application.dataPath:允许读取,不允许修改,读取方法和Unity Editor上面所述一致
  • Application.streamingAssets:允许读取,不允许修改,读取方法和Unity Editor上面所述一致
  • Application.persistentDataPath:可读可写,读取方法和Unity Editor上面所述一致
  • Application.temporaryCachePath:可读可写,读取方法和Unity Editor上面所述一致

Android

  • Application.dataPath:允许读取,不允许修改,但在Android上指向的是当前的apk,所以一般不会对其进行读取
  • Application.streamingAssets:允许读取,不允许修改,和别的平台读取有些区别,无法使用File类读取,读取方法如下
//只能使用UnityWebRequest,无法使用file类进行操作
string filePath = Application.dataPath + "/myFile.txt";
Uri uri = new Uri(filePath);  //这里使用uri可以简化很多操作,非常推荐,否则需要自己根据不同平台做处理
UnityWebRequest request = UnityWebRequest.Get(uri);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
    string content = request.downloadHandler.text;
    // 对文本内容进行处理
}
else
{
    Debug.LogError("Failed to read file: " + request.error);
}
  • Application.persistentDataPath:可读可写,读取方法和Unity Editor上面所述一致
  • Application.temporaryCachePath:可读可写,读取方法和Unity Editor上面所述一致

iOS

  • Application.dataPath:允许读取,不允许修改,读取方法和Unity Editor上面所述一致
  • Application.streamingAssets:允许读取,不允许修改,读取方法和Unity Editor上面所述一致
  • Application.persistentDataPath:可读可写,读取方法和Unity Editor上面所述一致
  • Application.temporaryCachePath:可读可写,读取方法和Unity Editor上面所述一致

路径注意事项

Application.dataPath

这个路径除了在Unity Editor中会做一些操作外,在打包后的平台上基本都不会进行什么操作,所以一般不对其进行什么特殊操作

Application.streamingAssets

这个目录在Android上是被压缩打包进Apk包里的,所以是没法直接用File类去读取的,需要用UnityWebRequest/www(已过时)去读取,在其他大部分平台都可以直接File类读取,一般这里都是存放一些需要内置的资源,用于在首次打开程序的时候去使用,例如放一些必要的ab包在这里,但是需要注意这里放太多资源是会严重影响包体积大小的,因此不必要的资源可以打ab包放到服务器上动态下载

Application.persistentDataPath

这个目录称为持久化目录,无法提前往里面存放资源,需要安装程序后才会生成,一般用于存在在服务器上下载的资源,例如ab包等,可读可写,是程序内最实用的路径,很多需要动态下载的资源都可以放在这里

Application.temporaryCachePath

这个目录称为临时目录,也是需要安装程序后生成的,一些临时数据可以下载存放在这里,但要注意的是,这个目录会受系统清理垃圾的影响,所以关键资源不要存放在这里

其他

通常情况下,UnityWebRequest的读写方式可以满足不同的平台的需要,所以当File类操作失败后,可以直接换成UnityWebRequest的读写方式,不过需要注意的是UnityWebRequest是需要协程的方式读写的,或者改造成async/await的方式(有时候不方便使用协程)。还有一个特别需要注意的点,UnityWebRequest接受string类型的路径或者uri类型的路径,如果传入的是string路径,在不同平台是有不同的要求的,因此建议统一使用uri的方式,Unity会帮我们处理这些差异,这样就可以避免很多问题,以下给出完整的UnityWebRequest示例:

//协程方式
IEnumerator ReadTextFile(string filePath)
{
    Uri uri = new Uri(filePath);
    UnityWebRequest request = UnityWebRequest.Get(uri);
    yield return request.SendWebRequest();
    if (request.result == UnityWebRequest.Result.Success)
    {
        string content = request.downloadHandler.text;
        // 对文本内容进行处理
        
        // 示例:输出文本内容到控制台
        Debug.Log(content);
    }
    else
    {
        Debug.LogError("Failed to read file: " + request.error);
    }
}
//异步方式
async void ReadTextFileAsync(string filePath)
{
    Uri uri = new Uri(filePath);
    UnityWebRequest request = UnityWebRequest.Get(uri);
    var asyncOperation = request.SendWebRequest();

    while (!asyncOperation.isDone)
    {
        await Task.Yield();
    }

    if (request.result == UnityWebRequest.Result.Success)
    {
        string content = request.downloadHandler.text;
        // 对文本内容进行处理

        // 示例:输出文本内容到控制台
        Debug.Log(content);
    }
    else
    {
        Debug.LogError("Failed to read file: " + request.error);
    }
}