Unity 加载资源
Posted 开着房车环游世界
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 加载资源相关的知识,希望对你有一定的参考价值。
直接把资源放在unity的目录里是不行的 打包的时候 不会打进去
要想打包到apk里 只有两种选择
1 放到 StreamingAssets 里 – Application.streamingAssetsPath
2 场景里有引用 他会自动打包进apk里
资源放到预制体里 并且预制体没在场景里 也不打包
先安装
https://github.com/Unity-Technologies/AssetBundles-Browser.git
使用文档
https://docs.unity.cn/Packages/com.unity.assetbundlebrowser@1.7/manual/index.html
创建两个ab包
1包是建模
2包是预制体 里面1包里的模型
也就是说 包2 是依赖 包1 的
如果只加载包2 unity是不会自动加载包1的
所以需要自己加载依赖关系
就是这样的
手机里没找到相对应的位置
apk安装包解压缩后 可以看到 ab包 在assets里
好 现在需要知道 ab包之间的依赖 咋办
string urlmf = Path.Combine(Application.streamingAssetsPath, "android");
AssetBundle ab3 = AssetBundle.LoadFromFile(urlmf);
AssetBundleManifest abManifest = ab3.LoadAsset<AssetBundleManifest>("assetbundlemanifest");
string[] str1 = abManifest.GetAllDependencies("ab1");
注意
这个 urlmf 是整个所有ab包的 也就是那个整个文件夹的
不是单独某个ab包的 (单独的加载不到)
举个例子 你生成的是安卓的ab包
那么 你会发现
在生成的ab包里 有一个 Android.manifest 文件
打开后 里面其实是 ab包之间的依赖关系
那如果现在想发包
哪写内容放到StreamingAssets 呢?
StreamingAssets 的特性是只读的
如果你把StreamingAssets 里的内容热更新到 persistent 那就会存在两份数据
去YooAsset群里问了下
群主的意思是
有一个原则,你可以参考。:首包保证玩家可以进入游戏体验15分钟即可。
其余内容,可以后续更新。
后续更新有2种方式,1:边玩边下,2:解锁新地图或新副本下载。
如果ab包在服务器怎么办
加载就行啦~
StartCoroutine(this.loadAB());
IEnumerator loadAB()
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(@"http://10.0.16.118:5000/ab2");
yield return request.SendWebRequest();
GameObject go1 = DownloadHandlerAssetBundle.GetContent(request).LoadAsset<GameObject>("PrefabA");
GameObject.Instantiate(go1);
现在
如果你需要把下载到的ab包 存到 persistentDataPath 里 咋办?
如果用普通下载到的 request.downloadHandler.data 直接 FileStream 写入是不行的
会报 NotSupportedException: Raw data access is not supported for asset bundles
需要这么写
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(@"http://10.0.16.118:5000/ab2");
FileInfo fileInfo = new FileInfo(Path.Combine(Application.persistentDataPath, "ab2"));
var handler = new DownloadHandlerFile(fileInfo.FullName);
request.downloadHandler = handler;
request.disposeDownloadHandlerOnDispose = true;
重点是 DownloadHandlerFile
可以查看文件
Unity开发实战探讨-资源的加载释放最佳策略简要心得
Unity开发实战探讨-资源的加载释放最佳策略简要心得
看过我另外一篇关于Unity资源释放随笔《Unity开发实战探讨-资源的加载释放最佳策略》如果觉得略微复杂,那么下面是一些比较简要的心得体会:
概括
常用资源加载的方法有三种:静态,Resources内部资源,AssetBundle外部资源
资源释放的方式 有二种:立刻释放和统一释放。
静态
静态就是资源直接放场景,静态资源无法立刻释放,但场景关闭由引擎统一释放,开发者无法干预,所以最为无脑。
但静态过于死板,除了整个场景生命周期中必须使用的资源外,不建议静态加载,为什么,消耗时间,占用内存;比如说,游戏场景持续使用的背景音乐,那么静态的确是最佳选择;但如果场景的开场要播放一个5M的音乐后面不再使用,这个资源用静态就是白白增加了5M音乐的加载时间和浪费了5M内存,得不偿失。
静态资源的加载策略是: 只加载必要固定的资源,或者极其微小损耗不大的资源。
释放策略是:由引擎负责。
Resources内部资源
Resources的资源一般和游戏一起打包,一般是游戏内使用的关键资源。
Resources主要加载一些动态的或者需要灵活处理的资源。加载的办法是先Reources.Load,然后GameObject.Instantiate,立刻释放的办法是Reources.UnloadAsset,统一释放的办法是Resources.UnloadUnusedAssets。
Resources的主要优点是使用灵活,缺点是开发复杂;加载的时候注意一个资源只需要Reources.Load一次,管理好Load出来资源的引用,尽量不要用静态引用,给释放制造困难。UnloadUnusedAssets前必须注意释放所有引用,所有Instantiate出来的对象必须销毁。
Resources的加载释放策略是: 只加载必须使用的资源,加载以后如果无需重复使用,或者使用频率非常的低,应该在明确使用完毕以后(如图片显示结束,音乐播放完毕)立刻用Reources.UnloadAsset释放。对于后续仍然会反复采用的资源,建议在内存中缓存引用,以防止后续加载不再反复调用Load函数,场景关闭前释放缓存,销毁所有实例化对象,等待Resources.UnloadUnusedAssets统一释放。UnloadUnusedAssets释放建议在当前场景完全销毁以后,再后续场景中执行最为稳妥。
AssetBundle外部资源
AssetBundle资源的机制基本和Resources类似,但可以独立打包,支持网络下载和文件读取,一般是游戏中使用的辅助资源。
AssetBundle机制要比Resources多一步,首先要通过AssetBundle.LoadFromXXX把AssetBundle加载到内存,然后使用AssetBundle.LoadAsset加载资源,最后GameObject.Instantiate为实例化对象。所以一个完整实例化的 AssetBundle存在三处内存引用,在释放策略上相对复杂。
AssetBundle的释放功能主要通过AssetBundle.Unload,而且也可以使用Reources.UnloadAsset和Resources.UnloadUnusedAssets进行释放。
AssetBundle的加载释放策略分两种情况:
加载完毕以后不再需要使用的资源包,可以再加载完毕以后立刻调用AssetBundle.Unload(false)释放资源包内存,而在此基础上,对于AssetBundle.LoadAsset以后并不再使用的资源,可以通过Reources.UnloadAsset释放,如需持续使用,也可能等待Resources.UnloadUnusedAssets后续统一释放。
加载完毕以后仍需持续使用的资源包,则必须保留AssetBundle引用,这种方式下,比较建议的方式是在场景完全销毁以后,一次性调用AssetBundle.Unload(true)完全释放改资源包和其所有加载资源。
以上是关于Unity 加载资源的主要内容,如果未能解决你的问题,请参考以下文章
Unity 框架QFramework v1.0 使用指南 工具篇:05. ResKit 资源管理&开发解决方案 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏