企业网站制作教程,90设计网素材官网,网站设计分析,想做游戏代理去哪里找本文介绍了 Unity 常用四种默认路径#xff0c;以及 AssetDataBase、Resources、AssetBundle 和目前最新的 Addressable 四种资源管理方式文中所有 API 均以版本 2019.3 为准本文原地址#xff1a;Unity学习—资源管理概览资源路径Application.dataPath官方文档只读#xff…本文介绍了 Unity 常用四种默认路径以及 AssetDataBase、Resources、AssetBundle 和目前最新的 Addressable 四种资源管理方式文中所有 API 均以版本 2019.3 为准本文原地址Unity学习—资源管理概览资源路径Application.dataPath官方文档只读Editor 可读写游戏数据相对路径即游戏安装路径PC 上路径会使用 / 分割文件夹 Unity Editor: 项目根路径/Assets Mac player: App 包路径/ContentsiOS player: App 包路径/AppName.app/Data Win/Linux player: 可执行数据文件夹路径WebGL: player data 文件的 绝对 url 地址 (不包含具体文件名)Android: 一般为 APK 路径 若使用 split binary build, 则为 OBB 路径Windows Store Apps: player data 文件夹的绝对地址Application.persistentDataPath官方文档可读写用于持久化数据存储在 iOS 和 Android 平台该路径指向设备的公共路径该目录不会随 App 升级而删除但可被用户直接删除persistentDataPath的路径由Bundle Identifier生成的 GUID 组成只要Bundle Identifier不变路径不变 iOS 会自动将 persistentDataPath 路径下的文件备份到 iCloudWindows Store Apps: %userprofile%AppDataLocalPackagesproductnameLocalStateiOS: /var/mobile/Containers/Data/Application/guid/DocumentsAndroid: /storage/emulated/0/Android/data/packagename/files 该路径由 android.content.Context.getExternalFilesDir 获得部分机型该路径会指向 SD 卡 Mac: ~/Library/Application Support/company name/product name 旧版本还可能为 ~/Library/Caches 或 ~/Library/Application Support/unity.company name.product nameUnity 会查询并使用以上路径中最早的路径 Application.streamingAssetsPath官方文档 官方手册只读Editor 可读写流数据存储的相对路径该目录下 Asset 在 Unity 编译时不会被 Unity 打包使其在运行时可直接通过路径获取可将资源放入 Assets 目录下任何名为 StreamingAssets文件夹StreamingAssets中资源可使用 I/O 读取但 WebGL 和 Android 平台下该路径为 URL不支持直接获取因此需使用 UnityWebRequest获取。若其他平台使用 UnityWebRequest 获取则需在路径前加上file:// 如 file:// Application.streamingAssetsPath /file.mp4Unity Editor, Windows, Linux players, PS4, Xbox One, Switch : Application.dataPath /StreamingAssets Mac: Application.dataPath /Resources/Data/StreamingAssetsiOS: Application.dataPath /RawAndroid: jar:file:// Application.dataPath !/assets (压缩后的 APK/JAR 文件) Application.temporaryCachePath可读写临时数据和缓存路径应用更新或覆盖安装时不会被清除手机空间不足时才可能会被系统清除路径示例读写权限说明说明资源加载推荐官方教程AssetDataBaseAssetDataBase 可在 Editor 环境下对项目 Asset 进行增删改查等操作可实现与 Unity 编辑器顶部工具栏 Assets 选项下基本相同的功能使用方法可参考官方手册 接口文档 Resources接口文档 可在项目 Assets 目录下任意位置创建Resources文件夹打包时 Unity 会整合所有位于Resources文件夹的 Asset 及其依赖并生成一个只读的 resources.assets 资产文件对于 Resources 目录中在游戏中被直接引用的资产则会被另外打包到 sharedassets0.assets 中 Resources 最佳实践官方的建议是不使用 Resources有以下几点原因Resources 文件夹会导致内存管理困难不适当使用 Resources 文件夹会加长应用启动和编译时间Resources 文件夹越多Asset 管理越困难Resources 系统降低项目针对指定平台使用自定义内容的能力并且无法实现增量更新AssetBundle 是 Unity 针对不同设备提供特定内容的主要工具适合使用 Resources 的场景因其简单快速的特性适合用于快速原型和实验开发但当正式开发时应当减少使用 适合以下条件都满足的状况 该内容不会占用大量存储资源该内容在整个生命周期都需要 该内容几乎不需要修改该内容在不同平台设备都一致 Resources 序列化项目编译时会将所有 Resources 目录下 Asset 和 Object 合并到一个序列化的 resources.assets文件该文件中还包含了类似于 AssetBundle 的元数据metadata和索引信息该信息包含了由对象名称转化得到的 GUID 和 Local ID 的查找树和对象位于序列化文件中的字节偏移量对于大部分平台查找树为时间复杂度为 O(n log(n)) 的平衡查找树随着 Resources 中对象的增加索引加载时间增长速度将超过线形增长速度 Resources 系统在 Splash 展示时初始化该过程不可跳过经观察在低端设备上10000 个 Asset 文件就会导致该过程长达数秒哪怕很多对象在第一个场景没用到也会被加载void Start()
{//Load a text file (Assets/Resources/Text/textFile01.txt)var textFile Resources.LoadTextAsset(Text/textFile01);//Load text from a JSON file (Assets/Resources/Text/jsonFile01.json)var jsonTextFile Resources.LoadTextAsset(Text/jsonFile01);//Then use JsonUtility.FromJsonT() to deserialize jsonTextFile into an object//Load a Texture (Assets/Resources/Textures/texture01.png)var texture Resources.LoadTexture2D(Textures/texture01);//Load a Sprite (Assets/Resources/Sprites/sprite01.png)var sprite Resources.LoadSprite(Sprites/sprite01);//Load an AudioClip (Assets/Resources/Audio/audioClip01.mp3)var audioClip Resources.LoadAudioClip(Audio/audioClip01);
}
AssetBundle官方手册 接口文档 AssetBundle 是外部资产的集合可独立于 Unity 构建过程外是 Unity 更新非代码内容的主要工具经常置于服务器上供用户终端动态获取AssetBundle 使开发者可以提交更小的应用包最小化运行时内存压力使终端可以选择性加载优化内容 该部分仅简单介绍 AssetBundle更多信息可见 Unity学习—AssetBundle AssetBundle 构建首先分配资产对象所在 AssetBundle在 Project 窗口选中需要打包的 Asset在 Inspect 窗口底部可见如下图内容底部 AssetBundle 后有两个输入选择框第一个为该资源所在 AssetBundle 名称第二个为 AssetBundle 变体名称 除此之外Unity 还提供了 AssetImporter.assetBundleName和AssetImporter.assetBundleVariant等接口将资源分配到 AssetBundle 2. 然后即可构建 AssetBundle 了使用BuildPipeline.BuildAssetBundles()即可构建 AssetBundle其中可配置参数输出路径、构建选项、目标平台 3. 或者可以使用 Unity 官方提供的工具管理 AssetBundle AssetBundles-Browser 官方手册 [MenuItem(Build Asset Bundles/Normal)]
static void BuildABsNone()
{BuildPipeline.BuildAssetBundles(Assets/MyAssetBuilds, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSX);
}
AssetBundle 构建选项BuildAssetBundleOptionsNoneUncompressedAssetBundle不压缩DisableWriteTypeTree不包含类型信息DeterministicAssetBundle使用哈希值作为 Asset IdForceRebuildAssetBundle强制重建IgnoreTypeTreeChanges增量构建检查时忽略类型树改动AppendHashToAssetBundleNameAssetBundle 名称后加哈希值ChunkBasedCompression使用 LZ4 压缩StrictMode构建过程中任务错误即构建失败DryRunBuild试运行DisableLoadAssetByFileName禁用名称查找资源可降低运行时内存提高加载效率DisableLoadAssetByFileNameWithExtension禁用带后缀名的名称查找资源可降低运行时内存提高加载效率AssetBundle 派发方式根据实际情况选择 AssetBundle 时随项目打包或后续通过网络下载一般移动平台由于初始安装大小和下载限制会选择安装后下载而主机和电脑则随项目打包 随项目打包有两个主要原因减少项目构建时长简化迭代开发针对无需单独更新的 AssetBundle 可放在 StreamingAssets 目录下发布可更新的初始修正内容用于节省用户初始安装后的时间和为后续修复做准备。但 StreamingAssets 不适用于该情况若不考虑自定义下载和缓存系统则可以使用 Unity 的缓存系统从 StreamingAssets 下载初始缓存一般推荐使用 UnityWebRequest下载 AssetBundle若下载包为 LZMA 压缩则缓存的为未压缩或使用 LZ4 重压缩的内容若缓存已满则 Unity 会删除最近最少使用的 AssetBundleUnity 内置的 AssetBundle 缓存系统用于缓存 UnityWebRequestAssetBundle.GetAssetBundle下载的包缓存仅以名称作为唯一标识。另外可通过重载方法可传入版本号开发者自己管理版本号缓存系统会比对版本号选择匹配版本或下载新包 缓存系统可通过 Caching.expirationDelay 和 Caching.maximumAvailableDiskSpace 修改最小未使用过期时间和最大缓存空间当缓存文件在过期时间内没被打开过即被删除或缓存空间不足则优先删除最近最少打开的缓存 IEnumerator GetText()
{using (UnityWebRequest uwr UnityWebRequestAssetBundle.GetAssetBundle(http://www.my-server.com/mybundle)){yield return uwr.SendWebRequest();if (uwr.isNetworkError || uwr.isHttpError){Debug.Log(uwr.error);}else{// Get downloaded asset bundleAssetBundle bundle DownloadHandlerAssetBundle.GetContent(uwr);}}
}
AssetBundle 加载有四种不同的 API 用于加载 AssetBundle但每个 API 的行为随压缩算法和平台而不同 AssetBundle.LoadFromMemoryAsync IEnumerator LoadFromMemoryAsync(string path)
{AssetBundleCreateRequest createRequest AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));yield return createRequest;AssetBundle bundle createRequest.assetBundle;var prefab bundle.LoadAssetGameObject(MyObject);Instantiate(prefab);
}
AssetBundle.LoadFromFile 该方法可高效地从硬盘加载未压缩或 LZ4 压缩的 Assetbundle加载 LZMA 压缩包时会先解压再加载到内存public class LoadFromFileExample : MonoBehaviour {function Start() {var myLoadedAssetBundle AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, myassetBundle));if (myLoadedAssetBundle null) {Debug.Log(Failed to load AssetBundle!);return;}var prefab myLoadedAssetBundle.LoadAsset.GameObject(MyObject);Instantiate(prefab);}
}
WWW.LoadfromCacheOrDownload5.6 及以前版本 旧方法已抛弃UnityWebRequestAssetBundle 5.3 及以后版本 先使用UnityWebRequest.GetAssetBundle创建请求再将请求传入DownloadHandlerAssetBundle.GetContent(UnityWebRequest)下载完成后可像AssetBundle.LoadFromFile 一样直接使用 assetBundle 对象 该方法使开发者更灵活处理下载数据选择临时存储或长期缓存避免不必要的内存使用。同时由于是原生代码没有托管堆栈扩展风险DownloadHandler 也不会保留下载数据进一步减少了内存开销LZMA 压缩包会在下载时解压并以 LZ4 重新压缩缓存可调用 Caching.CompressionEnabled 修改IEnumerator InstantiateObject()
{string uri file:/// Application.dataPath /AssetBundles/ assetBundleName; UnityEngine.Networking.UnityWebRequest request UnityEngine.Networking.UnityWebRequest.GetAssetBundle(uri, 0);yield return request.Send();AssetBundle bundle DownloadHandlerAssetBundle.GetContent(request);GameObject cube bundle.LoadAssetGameObject(Cube);GameObject sprite bundle.LoadAssetGameObject(Sprite);Instantiate(cube);Instantiate(sprite);
}
官方推荐尽量使用 AssetBundle.LoadFromFile该 API 在速度、磁盘使用和运行时内存使用方面都最高效需要下载则使用 UnityWebRequestAssetBundle Asset 加载同步异步加载 Asset 一共有六种 API 可使用同步方法一定比对应的异步方法快至少一帧LoadAsset (LoadAssetAsync) LoadAllAssets (LoadAllAssetsAsync) LoadAssetWithSubAssets (LoadAssetWithSubAssetsAsync)LoadAllAssets适合加载包中大部分或所有独立 Unity 对象时使用相较于多次重复调用另外两种 APILoadAllAssets速度要稍快一点。因此当 Asset 数量巨大且一次性需要加载的 Asset 少于 2/3 的时候建议将 AssetBundle 拆分成多个小包体再使用LoadAllAssets加载 LoadAssetWithSubAssets适合需要加载的对象内嵌了其他对象的情况若加载对象均来自于一个 Asset 且包中有许多其他无关对象则使用该 API 其他情况均用LoadAsset (LoadAssetAsync) Unity 对象加载时在主线程执行对象数据是在工作线程 worker thread任何线程不敏感的操作都在工作线程执行异步加载时会根据时间片限制每帧加载多个对象自 Unity 5.3 后对象加载就并行化了。多个对象在工作线程被反序列化、处理和集成当对象加载完成则触发 Awake 回调同步加载方法 AssetBundle.Load会暂停主线程知道加载完成它们还将加载过程进行时间切片以使对象集成所占用的帧时间不超过特定的毫秒数该值可通过Application.backgroundLoadingPriority设定 ThreadPriority.High: 最大 50 毫秒每帧ThreadPriority.Normal: 最大 10 毫秒每帧ThreadPriority.BelowNormal: 最大 4 毫秒每帧ThreadPriority.Low: 最大 2 毫秒每帧 在其他因素相同的情况下异步加载方法的调用到加载对象可用之间最小有一帧延迟导致异步加载方法比同步方法执行所需时间更长 AssetBundle 依赖根据运行环境可以使用两个不同的 API 自动追踪 AssetBundle 之间的依赖。Editor 环境下可使用AssetDatabase查询依赖使用AssetImporter访问和修改 AssetBundle 的分配和依赖运行时可以通过基于 ScriptableObject 的 AssetBundleManifest API 加载在 AssetBundle 构建期间生成的依赖项信息 当一个对象所在的 AssetBundle 被加载时该对象就被分配了一个唯一的有效实例 ID因此 AssetBundle 的加载顺序并不重要重要的是在加载该对象本身之前要优先把所有包含其依赖对象的 AssetBundle 加载好。Unity 不会自动加载子 AssetBundle具体可详见手册例 AssetBundle 1 中的 Material A 依赖于 AssetBundle 2 中的 Texture B若要正常加载与 AssetBundle 1 和 2 的加载顺序无关但一定要保证加载 Material A 时AssetBundle 2 已加载 在构建 AssetBundle 时Unity 创建一个包含每一个 AssetBundle 依赖信息的类型为 AssetBundleManifest 的序列化对象该文件存在一个与其他 AssetBundle 在同一打包路径下的单独的 AssetBundle 中且与父层文件夹名相同有两种 API 查询依赖 AssetBundleManifest.GetAllDependencies 获取 AssetBundle 的所有依赖层级AssetBundleManifest.GetDirectDependencies 获取 AssetBundle 直接依赖 因该 API 会生成字符串数组所以应尽量少用且避免性能高峰时使用官方建议大部分场合下在进入性能需求高的场景前尽可能多地加载对象尤其对于移动平台这种访问本地存储慢加载卸载对象引起内存流失会触发垃圾回收的平台 Asset 分包策略逻辑实体分包对象类型分包并发内容分包逻辑实体分包依据资源在项目功能块的使用位置如 UI、角色、环境和其他在生命周期中常出现的内容等分包将所有 UI 的纹理和布局数据分包将角色的模型和动画数据分包 将多场景共用的纹理和模型分包该分包方式适用于制作 DLC可以只下载单个实体而无需下载无变化的资源其关键点在于需要开发者清楚了解每个打包的资源所要用到的时机和位置对象类型分包该方式适用于针对多平台分包例如音频文件的压缩设置在 Windows 和 Mac OS 平台一样另外由于纹理压缩格式和设置等改变频率远低于脚本和预设体使用该分配方式可以使 AssetBundle 兼容更多的 Unity 版本 并发内容分包并发内容分包可理解为以关卡为分组依据将一个关卡内独有的角色、纹理、音乐等需要在同一时机加载的内容分为一包 Tips将常更新与不常更新内容分开 将需要同时加载的对象分为一组如一个模型其所需的材质和动画分为一组 若多个 AssetBundle 中的多个对象引用了其他 AssetBundle 中的单个 Asset则将依赖项分离到单独的包中以减少重复 确保两组完全不可能同时加载的对象不在用一包中如低清和高清材质包 若一个包中只有低于一半的对象被频繁加载可将其拆分 将一些同时加载的小包资源少于5到10个合并 若一个包中的对象仅是版本不同则可以使用 AssetBundle 变体 AddressableAddressable 系统为 Unity 新推出的资源管理系统整合了 Unity 直接引用Resources 和 AssetBundle 全部三种资源加载方式。通过可寻址资产的方式便捷地实现了内容包的创建和部署。Addressable 系统使用异步加载的方式实现从任何位置加载任何依赖项使得任何引用方式都更加便捷动态化注意需Unity 2018.3 及其以后版本Addressable 优势缩减迭代周期无需修改代码优化内容 自动依赖管理将请求内容的依赖项一同加载 自动内存管理对管理资源自动引用计数内容打包负责构建和解析引用链在将资源移动或重命名的情况下依然可实现本地和远端部署 配置文件可配置多个配置文件实现快速切换 Addressable 概念Addressable 由两个包组成Addressable Assets package主要功能 和 Scriptable Build Pipeline package依赖项Address资源的地址标记用于运行时查询 AddressableAssetData在项目 Assets 目录下用于存储 Addressable 资源的文件目录 Asset group构建时处理的 Addressable 资产组 Asset group schema数据构建时的配置 AssetReference可根据需求延迟初始化的直接引用对象 Asynchronous loading开发过程中无需更改代码也可修改资产位置和依赖项 Build script打包资产将 Address 和 Resources 映射 Label为运行时加载相似项目提供额外的 Addressable Asset 标志 Addressable 使用Addressable 安装打开顶部工具栏 Window - Package Manager找到 Addressables点击安装即可 2. 安装完成后 Addressable 的主要功能都可在顶部工具栏 Window - Asset Management - Addressables 中找到GroupsAddressable 分组工具SettingsAddressable 总体设置Profiles预设构建配置管理EventViewer监测引用计数工具Analyze用于分析打包情况检测重复等可自定义规则的分析工具Hosting模拟服务器3. 打开Group创建新的配置项目 Assets 目录下会自动创建一个 AddressableAssetData 目录无需直接改动该目录 Addressable Group 配置在 Addressables Groups 窗口右键或左上角 create 按钮即可创建 Group选中 Group在 Inspector 中修改设置Group 有三种配置项Content Packing Loading打包的构建和加载路径以及其他打包相关设置Content Update Restriction包更新限制Resources and Built In Scenes是否包含 Resources 或构建的场景添加 Asset 后构建 Addressable Group Addressables Groups 窗口Build New Build Default Build Script或者使用 API AddressableAssetSettings.BuildPlayerContent()Addressables Asset 配置和加载 添加 Addressable Asset 将资源直接拖入 Addressables Groups 窗口下分组内即可 或者在 Project 中选择任何 Asset 在 Inspector 下都可见名为 Addressable 的勾选框勾选即可将该 Asset可更改其 Addressable 名称此时该 Asset 就被添加到默认的 Addressables Group 中了 4. (可选) 更改资源名为资源添加 Label 5. 加载 Addressable Asset Addressables.LoadAssetAsyncT(string) 异步加载资源对象Addressables.InstantiateAsync(string) 场景中创建对象 或添加 AssetReference成员变量在 Inspector 可选择 AssetReference 引用的资源对象public class AddressablesExample : MonoBehaviour {GameObject myGameObject;...Addressables.LoadAssetAsyncGameObject(AssetAddress).Completed OnLoadDone;}private void OnLoadDone(UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandleGameObject obj){// In a production environment, you should add exception handling to catch scenarios such as a null result.myGameObject obj.Result;}
}
参考Unity读取内部、外部资源详解 Unity资源管理The Addressable Asset System 正式版应用