本文由 NRatel 历史笔记整理而来,如有错误欢迎指正。
资源管理是Unity游戏开发中的重头工作之一。
以下按【编辑器下】和 【运行时】,共十多个步骤,一览总体流程(内容巨大,不细展开)。
一、资源导入Unity【编辑器下】
Unity资源导入设置方式选择-CSDN博客文章浏览阅读428次,点赞6次,收藏8次。一种可保存和重复应用的资源导入配置模板。需先在 Inspector 窗口中为某种类型资源(如 Texture、Model、AudioClip)配置好所有导入设置后,将其保存为一个 .preset 文件。然后在 Inspector 窗口中手动拖拽或应用 Preset 到选中的资源(可多选资源批量应用)。支持只应用部分字段。可在 Edit -> Project Settings -> Preset Manager 中设置默认 Preset。https://blog.csdn.net/NRatel/article/details/151068515
二、制作游戏【编辑器下】
创建Unity内资源
资源加工
三、资源分组【编辑器下】
1、一般分组策略
⑴、按逻辑实体分组
⑵、按类型分组
⑶、按并发内容分组
2、两种准备方式
⑴、设置ab标签(assetBundleName 和 assetBundleVariant)
可以以/分隔的字符串作为标签,将成为ab的输出子路径
unity设置ab标签时会统一转为小写
后缀应设置为常规 .unity3d 或 .bundle,安卓 mainTemplate.gradle 中 aaptOptions 的 noCompress 的 BUILTIN_NOCOMPRESS默认为此两种后缀
⑵、自己利用特定规则构建 AssetBundleBuild[]
⑶、注意事项
①、无ab标签的资源被重复打入不同ab的问题
解决方式1:将X及依赖X的Y、Z资源,全打入一个ab中(可能使ab过大,后期可能还要拆分)
解决方式2:接能保证不被同时加载(只占硬盘不占内存,可忍)
解决方式3:提出公共依赖作为单独ab(彻底解决,但增加复杂度)
②、循环依赖问题
③、ab变体问题
④、图集打包问题
⑤、嵌套预设打包问题
⑥、Shader及其变体打包问题
⑦、压缩格式选择问题(LZMA、LZ4、不压缩)
四、资源打包【编辑器下】
1、两种AB打包方式
⑴、按照已设置的标签打 BuildPipeline.BuildAssetBundles(); 是增量的(已打过未变化的不会重新打)
⑵、按照自己构建的数组打 BuildAssetBundles(AssetBundleBuild[] builds);
2、BuildAssetBundleOptions 选项
⑴、BuildAssetBundleOptions.None 默认使用LZMA压缩
⑵、BuildAssetBundleOptions.StrictMode 有问题暴露出来
⑶、BuildAssetBundleOptions.DisableLoadAssetByFileName(从ab中加载资源时可以只传入文件名,而不用传入完整路径和后缀)BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension(从ab中加载资源时可以只传入文件名和后缀,而不传入完整路径)应该明确加载,所以统一按路径加载,禁用这两种快捷方式,以节省性能注意:unity设置ab标签时会统一转为小写,加载时win平台大小写不敏感,但移动平台敏感所以,应统一为小写。
⑷、AssetBundleStripUnityVersion 去掉,避免提升Unity小版本导致所有ab变化
⑸、DisableWriteTypeTree 建议不要动,向下兼容,省心,否则提升Unity版本之后必须记得将全部资源更新一次
3、生成/拷贝非AB资源,并加密&压缩
五、资源版本化【编辑器下】
1、 加载原始无版本化资源清单
2、创建版本化资源清单
3、设置摘要信息
4、处理每个资源文件(改名拷贝)
5、保存版本化清单文件
六、资源发布
1、上传资源到远程资源服务器(打包App时、热更时)
2、或内置资源到包内(打包App时)
七、App打包
见我其他打包相关文章
八、App上架
见我其他传包相关文章
九、App更新【运行时】
强制更新(更新后才可进入,点击更新跳转到应用商店)
非强制更新(可进入老版本)
十、资源更新(热更)【运行时】
1、根据项目需要,两种方式选择
方式1、直接下载到 Application.persistentDataPath
方式2、先下载到 Application.temporaryCachePath,再 拷贝到 Application.persistentDataPath
2、适应性/优缺点对比
优点:方便对资源进行自定义压缩/解压。像单机类型的还能不必要求他更新完成
缺点:占硬盘(极限情况下2倍)、多了拷贝/解压过程(拖慢进入时间,多了运行时候io)
3、按版本资源清单增量下载/删除
获取版本资源完整清单
合并历史完成/未完成
计算最新需下载清单
按清单下载
4、下载方法
下载普通文件
UnityWebRequest.Get(string uri)
下载 AB文件
如果不是下载即用,可直接按普通文件下载
UnityWebRequestAssetBundle.GetAssetBundle(string uri)
5、下载实现——异步单步任务(底层支持、独立模块)
成功、失败回调
可主动终止
异步多步并行任务(底层支持、独立模块)
成功、失败、进度回调
可主动终止
限制同时最多
可选择失败时是否终止
可设置优先级?
6、下载实现——单个文件下载器(异步单步任务的一个实现)(内部可能性全部提出为配置)
url【传入配置】
保存位置【传入配置】
是否断点下载【传入配置】
大文件需要断点续传
重试次数【传入配置】
默认0
使用协程/子线程执行(先固定协程吧)
成功、失败回调
7、下载实现——文件列表下载器(使用异步多步任务)
整体下载完成后操作(完成回调中)
如:整体完成后统一解压
处理下载失败的情况(失败回调中)
考虑:若是网络问题应该立即终止,若是文件问题可先下载其他文件
单个文件下载完成后操作(进度回调中)
计数
8、下载实现——多列表下载器(合并下载N个文件列表)(多个分包时)
方式一:串行下载多个列表
方式二:将多个列表合并为一个列表;再下载这个大列表
十一、加载AB到内存【运行时】
1、加载/创建方法
⑴、从内存区域创建 AssetBundle.LoadFromMemory(byte[] binary)
可用于ab加密解密,但速度慢且内存会至少翻倍,不推荐使用
⑵、从本地硬盘加载 AssetBundle.LoadFromFile(string path)
支持加载任意压缩类型的ab,LZMA格式将在内存中被解压
在移动设备中,只会将 ab 的 头部数据加载进内存,其他的数据保留在磁盘中
在 Unity 编辑器中,会将 ab 的全部数据加载进内存。这会使 Profiler 出现内存峰值,实际设备不会出现
⑶、AssetBundle.LoadFromStream(Stream stream)
支持任意压缩类型,LZMA将在内存中解压,速度与LoadFromFile类似,可用于ab加密解密
2、支持可寻址加载
一个自定义加载地址,无论资源在 Assets 下的任意子路径中(使资源可随意移动)
一个自定义加载地址,无论ab在 Assets目录(编辑器下),还是在 stramingAssets 或 persistDataPath 目录,还是在远程(可不支持)
3、依赖处理
递归加载其依赖项,以保证LoadAsset时无引用丢失
十二、加载AB内资源到内存【运行时】
加载方法 ab.LoadAsset(string name)
十三、创建游戏对象/组件实例【运行时】
根据资源类型不同,复制 或 引用资源
Prefab:复制
Texture、Shader:引用
Mesh、Material :复制 或 引用Shared
十四、销毁游戏对象/组件实例【运行时】
1、销毁/解除引用资源
销毁 GameObject.Destroy()
以非附加方式加载场景,Application.LoadLevel()
将销毁当前场景中的所有对象(部分对象除外)
DontDestroyOnLoad 的对象不会被此方法销毁
HideFlags 包含或是 DontSave 的对象不会被此方法销毁
解除引用如 xxx.texture = null 等
十五、卸载内存中资源【运行时】
1、卸载方法
Resources.UnloadAsset(Object assetToUnload)
Resources.UnloadUnusedAssets()
当内容较多时可能卡顿
以非附加方式加载场景时,将销毁当前场景中的所有对象并自动调用本方法
HideFlags 包含或是 DontUnloadUnusedAsset 的资源不会被此方法卸载(只能主动指定卸载)
十六、卸载AB【运行时】
1、卸载方法
ab.Unload(bool unloadAllLoadedObjects)
参数指定true时:卸载ab header,同时卸载所有从ab内加载的资源对象(即使正在场景中被使用)(应尽量使用此方式)
参数指定false时:只卸载ab header,被引用的ab内资源将驻留(该资源将和ab无关)(后续可使用Resources.UnloadUnusedAssets清理)
AssetBundle.UnloadAllAssetBundles(bool unloadAllObjects);
2、ab引用计数,代理卸载