尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Unity 中 Application 四种常用目录总结

Unity 中 Application 四种常用目录总结 Unity 中Application提供了多种目录路径用于不同场景以下是四种常用目录路径的区别、用途和跨平台下的具体路径示例以下路径仅为常见示例。实际路径会受 Unity 版本、操作系统版本、应用标识和安装位置影响运行时应始终使用Application返回的值不要硬编码绝对路径。1.Application.dataPath描述指向目标平台上的游戏数据位置。在编辑器中指向项目的Assets目录构建后的位置和形式因平台而异不一定是普通文件夹。用途在 Player 中通常应按只读位置处理不要用于保存存档或配置。它不是加载 Unity 导入资源的通用入口此类资源应通过 Addressables、AssetBundle、Resources等 Unity API 加载。示例路径Windows编辑器:C:/YourProject/AssetsWindows打包:C:/YourGame/GameName_DataAndroid:/data/app/安装目录/包名-随机后缀/base.apk或/data/app/包名-随机后缀/base.apk通常是 apk 自身路径具体层级由系统决定iOS:/var/containers/Bundle/Application/YourAppID/YourAppName.app/Data示例代码Windows:stringdataPathApplication.dataPath;Debug.Log(Data Path on Windows: dataPath);// 输出示例: C:/Users/Username/Projects/MyGame/Builds/MyGame_DataAndroid:stringdataPathApplication.dataPath;Debug.Log(Data Path on Android: dataPath);// 输出示例: /data/app/~~a1b2/com.company.mygame-c3d4/base.apk注意Android 上dataPath通常返回apk 文件本身的路径而非可遍历目录部分旧版系统只有“包名 一个随机后缀”这一层新版系统可能还有~~随机值外层。哈希数量和内容都由 Android 包管理器决定重新安装或更新后也可能变化。使用 Split Application Binary 时Unity 文档说明该值可能指向 OBB。读取需要原样随包发布的文件应使用streamingAssetsPath加载 Unity 资源则应使用对应的资源加载 API。2.Application.persistentDataPath描述指向应用的持久化存储目录适合保存需要长期存储的数据如存档、设置。在应用标识保持不变的前提下数据通常不会因应用更新或重启丢失卸载应用、清除应用数据或清理浏览器站点数据后仍可能丢失。用途可读写适合存储游戏存档、设置文件等。示例路径Windows:C:/Users/YourUsername/AppData/LocalLow/CompanyName/GameNameAndroid大多数设备:/storage/emulated/0/Android/data/YourPackageName/filesiOS:/var/mobile/Containers/Data/Application/YourAppID/DocumentsWebGL:/idbfs/urlHash映射到浏览器 IndexedDB哈希与页面所在 URL 目录有关示例代码Windows:stringpersistentDataPathApplication.persistentDataPath;Debug.Log(Persistent Data Path on Windows: persistentDataPath);// 输出示例: C:/Users/Username/AppData/LocalLow/Company/ProductNameAndroid:stringpersistentDataPathApplication.persistentDataPath;Debug.Log(Persistent Data Path on Android: persistentDataPath);// 输出示例: /storage/emulated/0/Android/data/com.company.mygame/filesAndroid 上通常由Context.getExternalFilesDir()返回应用专属外部存储目录不需要传统的共享存储读写权限。Player Settings 中的Write Permission不用于切换persistentDataPath。部分老旧设备的实际位置可能不同因此不要写死路径。3.Application.streamingAssetsPath描述指向Assets/StreamingAssets文件夹。构建时其中的文件会基本保持原样随应用发布在 Player 中应按只读内容处理。用途存储需要原样随应用分发、并通过文件名或 URL 访问的内容例如初始配置、数据库和媒体文件。示例路径Windows编辑器:C:/YourProject/Assets/StreamingAssetsWindows打包:C:/YourGame/GameName_Data/StreamingAssetsAndroid:jar:file:///data/app/YourPackageName/base.apk!/assetsiOS:/var/containers/Bundle/Application/YourAppID/YourAppName.app/Data/RawWebGL:https://yourhost/yourbuild/StreamingAssets示例代码Windows:stringstreamingAssetsPathApplication.streamingAssetsPath;Debug.Log(Streaming Assets Path on Windows: streamingAssetsPath);// 输出示例: C:/Users/Username/Projects/MyGame/Builds/MyGame_Data/StreamingAssetsAndroid:stringstreamingAssetsPathApplication.streamingAssetsPath;Debug.Log(Streaming Assets Path on Android: streamingAssetsPath);// 输出示例: jar:file:///data/app/com.company.mygame-1/base.apk!/assets重要Android 与 WebGL 上该路径不是普通文件系统路径前者通常位于 apk 内后者是 URL不能使用同步FileAPI 访问必须用UnityWebRequest读取。详见下方「常见坑」。4.Application.temporaryCachePath描述指向临时存储目录数据可能会被系统清理。适合存储缓存文件、临时数据。用途可读写适合存储下载的临时数据等。示例路径Windows:C:/Users/YourUsername/AppData/Local/Temp/CompanyName/GameNameAndroid当前常见 Unity Player:/storage/emulated/0/Android/data/YourPackageName/cacheiOS:/var/mobile/Containers/Data/Application/YourAppID/Library/Caches示例代码Windows:stringtemporaryCachePathApplication.temporaryCachePath;Debug.Log(Temporary Cache Path on Windows: temporaryCachePath);// 输出示例: C:/Users/Username/AppData/Local/Temp/Company/ProductNameAndroid:stringtemporaryCachePathApplication.temporaryCachePath;Debug.Log(Temporary Cache Path on Android: temporaryCachePath);// 输出示例: /storage/emulated/0/Android/data/com.company.mygame/cacheAndroid 同时还存在由Context.getCacheDir()提供的内部缓存目录/data/user/0/包名/cache。当前常见 Unity Android Player 的temporaryCachePath使用getExternalCacheDir()对应的应用专属外部缓存目录不同 Unity 和系统版本仍应以运行时日志为准。缓存随时可能被系统回收不要用来存唯一副本只适合放“丢了可以重新下载或重新生成”的内容。总结属性功能描述可读/可写示例路径Windows/Android/iOSApplication.dataPath目标平台的游戏数据位置Player 中按只读处理C:/YourGame/GameName_Data//data/app/.../base.apk//YourAppName.app/DataApplication.persistentDataPath应用持久化数据目录可读可写C:/Users/.../LocalLow/...//storage/emulated/0/Android/data/.../files//DocumentsApplication.streamingAssetsPathStreamingAssets 文件路径只读C:/YourGame/.../StreamingAssets/jar:file:///.../base.apk!/assets//YourAppName.app/Data/RawApplication.temporaryCachePath临时缓存目录可读可写C:/Users/.../AppData/Local/Temp/...//storage/emulated/0/Android/data/.../cache//Library/CachesApplication.dataPath表示目标平台上的游戏数据位置不应用作存档目录或通用资源加载入口。Application.streamingAssetsPath用于访问需要原样随包发布的文件Android 和 WebGL 上应使用UnityWebRequest。Application.persistentDataPath用于保存需要跨运行保留的数据更新通常不会清除但卸载、清除应用数据或应用标识变化可能使旧数据丢失或无法访问。Application.temporaryCachePath用于存储可重新下载或重新生成的缓存系统可能在存储不足等情况下清理并非应用退出时必然清空。这些路径在不同平台上的具体路径可能会有所不同但它们的用途和行为是相似的。通过正确使用这些路径可以确保应用程序在不同平台上都能正确地管理和访问文件。常见坑与实践建议1. StreamingAssets 在 Android / WebGL 上不能用 File APIAndroid 上 StreamingAssets 通常位于 apkzip内部路径形如jar:file://...!/assetsWebGL 上则是一个 URL。两者都不是可供同步FileAPI 直接访问的普通文件系统路径应统一用UnityWebRequestIEnumeratorLoadConfig(stringrelativePath){stringpathPath.Combine(Application.streamingAssetsPath,relativePath);// 普通本地路径转换为正确转义的 file URIAndroid/WebGL 的 URL 保持不变stringurlpath.Contains(://)?path:newUri(path).AbsoluteUri;using(varreqUnityWebRequest.Get(url)){yieldreturnreq.SendWebRequest();if(req.result!UnityWebRequest.Result.Success){Debug.LogError($加载失败:{req.error});yieldbreak;}stringtextreq.downloadHandler.text;// 处理 text ...}}2. iOS 的 Documents 会被 iCloud 备份persistentDataPath在 iOS 上映射到Documents其内容默认参与 iCloud/iTunes 备份。往里写入大量可重新下载的资源热更包、AB 包、视频缓存会撑大用户的备份体积属于 App Store 审核会关注的问题。处理方式可再下载的内容放temporaryCachePath必须放在 Documents 下的用原生接口给目录打上NSURLIsExcludedFromBackupKey标记。3. 路径拼接统一用 Path.Combine不要依赖 Unity 返回路径所使用的分隔符样式。手工用字符串相加容易出现重复、缺失或混合分隔符在部分原生库、URI 和路径比较逻辑里会出问题// 推荐stringsavePath.Combine(Application.persistentDataPath,Save,slot0.json);// 目录可能不存在写文件前先建Directory.CreateDirectory(Path.GetDirectoryName(save));File.WriteAllText(save,json);4. WebGL 持久化需要确认同步完成WebGL 上persistentDataPath由内存文件系统与浏览器 IndexedDB 共同实现。文件写入完成并不等于 IndexedDB 已同步完成具体的自动同步行为还可能随 Unity 版本和模板实现而变化。如果业务需要明确知道存档已经落盘可通过.jslib调用 Emscripten 的FS.syncfs(false, callback)并在回调成功后再提示“保存完成”或允许用户离开页面。PlayerPrefs.Save()只保证保存 PlayerPrefs不应当作任意文件的通用同步接口。刷新页面、关闭标签页和浏览器隐私策略都可能影响最终结果必须在目标浏览器上测试。5. 编辑器与真机行为不一致编辑器下streamingAssetsPath就是Assets/StreamingAssets这个真实目录File API 完全可用——这会掩盖第 1 条的问题导致编辑器正常、打包到 Android 就崩。涉及这些路径的代码必须在真机上验证。同理dataPath在编辑器中指向Assets构建后的值则因平台而异Windows/Linux 通常指向xxx_DataAndroid 通常指向 apkWebGL 返回 URL。任何依赖它做相对定位的逻辑都要在目标平台验证。6. persistentDataPath 依赖应用标识和平台配置persistentDataPath的稳定性依赖平台相关的应用标识Windows 路径通常包含 Player Settings 中的 Company Name 和 Product NameAndroid 主要取决于 Package NameiOS 与 Bundle Identifier 相关WebGL 路径哈希与承载页面所在的 URL 目录有关。上线后修改这些标识或移动 WebGL 页面目录可能使应用访问到不同的持久化目录进而读不到旧存档。发版前应确认相关标识已定稿确需修改时应提前设计存档迁移方案。Android 脱敏案例同一 Unity 应用在模拟器和真机上的路径差异以下示例已脱敏仅用于展示 Android 系统可能生成的路径格式。包名、随机后缀、ADB 序列号、设备型号、版本号、用户名和本地安装目录均使用占位符不能据此反推出具体设备或应用。1. Android 模拟器实例 0环境信息实例名称Android 模拟器实例 0ADB 设备emulator-serial包名com.example.game类型脱敏示例路径Application.dataPath对应的主 APK/data/app/com.example.game-随机后缀/base.apkApplication.streamingAssetsPath对应地址jar:file:///data/app/com.example.game-随机后缀/base.apk!/assetsApplication.persistentDataPath/storage/emulated/0/Android/data/com.example.game/filesApplication.temporaryCachePath对应的应用专属外部缓存目录/storage/emulated/0/Android/data/com.example.game/cacheAndroid 内部应用数据根目录/data/user/0/com.example.gameAndroid 内部缓存目录/data/user/0/com.example.game/cache某些模拟器使用只有一个安装目录层级的格式/data/app/ └── com.example.game-随机后缀/ ├── base.apk ├── split_config.abi.apk └── 其他 split APK模拟器在 Windows 上通常还会有一个宿主虚拟机目录例如C:\Path\To\AndroidEmulator\vms\instance0Android 文件通常封装在虚拟磁盘文件中不会与 Android 内部路径一一对应。2. Android 真机环境信息设备型号device-modelAndroid 版本android-versionADB 设备device-serial包名com.example.game新版 Android 常见的两级随机安装目录格式如下/data/app/ └── ~~安装容器随机值/ └── com.example.game-应用随机后缀/ └── base.apk对应的常见应用目录为/storage/emulated/0/Android/data/com.example.game/files /storage/emulated/0/Android/data/com.example.game/cache /data/user/0/com.example.game /data/user/0/com.example.game/cache持久化目录中可能包含以下类型的文件files/ ├── SaveFile.dat ├── Main/ ├── Bundles/ ├── Unity/ ├── il2cpp/ └── customloadablecontents/普通adb shell通常使用 UID2000(shell)不能遍历其他应用的内部私有目录如果设备已经 Root可以使用su以 root 身份执行只读命令adb-sdevice-serialshellid# uid2000(shell) ...adb-sdevice-serialshellsu -c ls -la /data/user/0/com.example.gameadb root与su不是一回事量产系统中的adbd通常拒绝adb root但已 Root 的设备仍可能支持adb shell su -c 命令。3. 脱敏案例的结论对比项模拟器示例真机示例APK 安装目录层级/data/app/包名-随机值//data/app/~~随机值/包名-随机值/安装路径中的随机值数量一个两个persistentDataPath/storage/emulated/0/Android/data/com.example.game/files相同普通 ADB 读取外部应用目录通常可以受 Android 版本和系统策略影响普通 ADB 读取/data/user/0/...通常不可以通常不可以使用 root shell 读取内部目录取决于模拟器 Root 设置取决于设备是否安装并授权su结论dataPath的安装目录结构不稳定随机后缀不应写入代码persistentDataPath的目录结构相对稳定但业务代码仍应始终读取 Unity 在运行时返回的实际路径。本节中的路径是脱敏示例不对应任何特定应用、设备或用户环境。实际排查时请注意不要在公开文章中发布真实包名、APK 安装路径、ADB 序列号、设备型号、用户目录、虚拟机路径、存档文件名和精确容量。补充说明Unity API 文档中属性后标注的Read Only首先表示该 C# 属性只有 getter、不能给路径属性赋值目标目录是否可写仍取决于具体平台和目录类型。persistentDataPath在 tvOS 上不受支持并可能返回空字符串。如果项目面向 tvOS应使用平台支持的存储方案并单独测试。以上路径示例只能用于帮助理解业务代码应始终以运行时返回值为准。参考文档Unity Scripting APIApplication.dataPathUnity Scripting APIApplication.persistentDataPathUnity Scripting APIApplication.streamingAssetsPathUnity Scripting APIApplication.temporaryCachePath
返回列表