Unity学习----【进阶】Addressables(二)--加载资源与打包及更新
·来源于唐老狮的视频教学,仅作记录和感悟记录,方便日后复习或者查找
一.使用Addressables加载资源的方法
之前我们学习过通过资源引用变量来直接指定加载资源,但是这种方法需要我们手动去指定要加载的资源,当资源更新变化的时候,就又要去手动更改,比较麻烦。接下来介绍用变量的名字和标签来加载一个或者多个资源的静态方法
1.加载单个资源
1.1.加载资源
handle = Addressables.LoadAssetAsync<GameObject>("Cube");handle.Completed += (handle) =>{//判断加载成功if (handle.Status == AsyncOperationStatus.Succeeded)Instantiate(handle.Result);//一定要是 加载完成后 使用完毕后 再去释放//不管任何资源 只要释放后 都会影响之前在使用该资源的对象Addressables.Release(handle);};
①使用方法:Addressables.LoadAssetAsync<加载资源类型>(加载资源的名字 或 标签)


②它返回的是一个句柄类型的变量,我们在它的委托事件Completed中去执行资源加载完成后需要做的事情。Complete的委托参数其实就是这个句柄本身,它可以用于状态判断和获取加载好的资源。
③如果成功加载,则handle.Status的变量会被设定为 AsyncOperationStatus.Succeeded这个枚举,获取的变量被存放在Result属性中
④当我们不再使用这个资源之后,就需要用Addressables.Release(handle);来释放句柄,避免内存占用
1.2.加载场景
//参数一:场景名
//参数二:加载模式 (叠加还是单独,叠加就是两个场景一起显示,单独就是只保留新加载的场景,正常情况为单独)
//参数三:场景加载是否激活,如果为false,加载完成后不会直接切换,需要自己使用返回值中的ActivateAsync方法
//参数四:场景加载的异步操作优先级
Addressables.LoadSceneAsync("SampleScene", UnityEngine.SceneManagement.LoadSceneMode.Single, false).Completed += (obj) => {//比如说 手动激活场景obj.Result.ActivateAsync().completed += (a) => {//然后再去创建场景上的对象//然后再去隐藏 加载界面//注意:场景资源也是可以释放的,并不会影响当前已经加载出来的场景,因为场景的本质只是配置文件Addressables.Release(obj);};
};
①加载场景有一个特定的方法Addressables.LoadSceneAsync(),里面的参数看注释
②同样可以在它加载完成之后去做一些事情
注意:
①Release一般我们最好在这个物体被销毁的时候再去释放,即使是实例化一个物体,不然可能有一些引用依赖会丢失(例如材质)
②我们可以写一个脚本,统一对这些句柄的创建和销毁进行管理(通过存储在字典容器中),这样可以避免这些句柄散落地到处都是
2.加载多个资源
2.1.根据单个名字或者标签加载多个资源
//加载资源
//参数一:资源名或标签名
//参数二:加载结束后的回调函数
//参数三:如果为true表示当资源加载失败时,会自动将已加载的资源和依赖都释放掉;如果为false,需要自己手动来管理释放
AsyncOperationHandle<IList<Object>> handle = Addressables.LoadAssetsAsync<Object>("Red", (obj) =>
{print(obj.name);
});
①通过Addressables.LoadAssetsAsync<Object>("Red", (obj) =>
{
print(obj.name);
});来加载多个资源。第一个参数传入资源或者标签名,第二个参数传入对获取的每一个资源做什么(每一个资源加载好后都会使用一次该函数),第三个参数一般我们不填默认为true。
//如果要进行资源释放管理 那么我们需要使用这种方式 要方便一些
//因为我们得到了返回值对象 就可以释放资源了
handle.Completed += (obj) =>
{foreach (var item in obj.Result){//print(item.name);}//释放资源Addressables.Release(obj);
};
//注意:我们还是可以通过泛型类型,来筛选资源类型
②当然,我们也可以获取它的加载句柄,里面的结果值是一个Object列表。我们可以在这里手动遍历以处理每一个获取的物体
注意:传入的泛型也可以作为筛选资源的一种条件
2.2.根据组合名字和标签加载多个资源
//参数一:想要加载资源的条件列表(资源名、Lable名)
//参数二:每个加载资源结束后会调用的函数,会把加载到的资源传入该函数中
//参数三:可寻址的合并模式,用于合并请求结果的选项。
//如果键(Cube,Red)映射到结果([1,2,3],[1,3,4]),数字代表不同的资源
//None:不发生合并,将使用第一组结果 结果为[1,2,3]
//UseFirst:应用第一组结果 结果为[1,2,3]
//Union:合并所有结果 结果为[1,2,3,4]
//Intersection:使用相交结果 结果为[1,3]
//参数四:如果为true表示当资源加载失败时,会自动将已加载的资源和依赖都释放掉
// 如果为false,需要自己手动来管理释放
List<string> strs = new List<string>() { "Cube", "HD" };
Addressables.LoadAssetsAsync<Object>(strs, (obj) => {print(obj.name);
}, Addressables.MergeMode.Intersection);//注意:我们还是可以通过泛型类型,来筛选资源类型
①方法和之前差不多,只是这次传入的是一个字符集合(列表等继承了迭代器接口的都行)。
②第三个参数合并模式决定了各个字符搜索到的资源是执行交集还是并集
二.打包的方法与注意事项
0.资源打包与加载到的位置
默认打包与存储位置:
①在这里我们可以查看和设置打包存储与读取的路径的默认参数值
②这里[]{}都是一个程序中设定好的变量值。
点击这里可以新创建一个概述文件进行配置
打包与加载目录生成设置
这里点击打开可寻址资源设置
可以在这里选择我们需要的的概述文件设置
之后在下面我们可以选择生成打包与加载的目录的路径(这里默认一个是本地的,一个是远程的)
注意上面那个Build Remote Catalog是构建远程包目录,需要加载远程包的话一定要勾上
1.本地打包与使用
1.1.打包
这里我们设置为本地(因为要打本地包)
- 可以设置每一组是使用本地打包路径还是远程打包路径(这里本地还是远程也是受设置中选择的哪一个概述文件的影响)
都设置完成后我们就可以点击Build来构建包

在默认设置下,我们应该是可以在这里看到打出去的本地AB包的
1.2.使用
在测试AB包是否打包成功并且并能被使用的时候,我们会把这个播放脚本模式选择为第三种
然后我们按之前学习的方法加载并实例化一个资源
然后点击运行我们可以看到资源被成功加载出来(这里虽然名字叫Cube,但是它是一个圆柱体的)
在我们把整个项目构建打包出去之后
如果用的是默认的打包路径,那他会帮助我们把AB包放入到StreamingAssets文件夹下。否则只能我们自己手动去把这些包给放入到其中。
2.远程打包与使用
2.1.打包
远程打包其实就是添加一些设置而已
这里我们找到可寻址资源设置的配置文件,把加载和打包路径的目录设置为Remote
然后把需要打包为远程包的组的构建和加载路径也设置为Remote即可
然后把这些资源打包出去
之后我们应该是可以在项目的一个叫ServerData的文件夹下面,看到这些被打出去的AB包的
2.2.使用
先去项目设置里把HTTP下载设置为允许
这里使用远端包我们可以用两种方式来把本机模拟为服务器
Unity自带的功能(不推荐)
打开这个Addressables Hosting窗口,创建一个Local Hosting,并点击Enable启用。然后我们可以看到它下面说有两个文件夹都被作为服务器文件夹了。这里我们可以看到就是之前本地包和远程包打包到的文件。
之后也是点击运行之后,如果没有出Bug的话就会看到下面很多的调试信息打印,以及加载出来的资源。
但是这个方法主要是经常会出现一些bug,导致加载或者访问不出来,所以我们一般不推荐用这个来测试。
第三方HFS(推荐)
先下载这么一个应用程序
打开并设置它的端口号
然后在概述文件中把加载路径设置为IP地址和端口号与他一致,同时指定加载的文件
之后把作为服务器资源的文件夹拖入其中
这样在运行之后,也可以看到资源被顺利加载出来,同时看到服务器有被访问到的打印信息
- 这个方法比较稳定且灵活,不容易卡死遇到乱七八糟的bug,推荐使用的
三.更新包
操作:
更新包对于本地包而言,需要整个项目再构建打包一次才能够被使用,适合于大版本更新的时候。
但是对于远程包而言,项目不需要再打包,只需要打包资源即可,适合于小版本的资源更新。
我们在这里点击Update a Previous Build来更新资源
这里我们构建一个项目出去并运行,可以看到它同样可以访问到我们的资源服务器中的资源
我们在编辑器中尝试更新一下这个加载的模型,拖入一个新的预制体,并把名字和标签设定和之前一样的。
点击更新包,可以看到下面跳出来成功打包的窗口
再次启动之前构建好的程序,我们可以看到里面加载的预制体被成功更新为了真的立方体!
组的更新方法设定:
我们在更新组的可以选择更新的限制:
默认情况下不打勾:更新的时候重构整个包(适合当包中大多数资源都发生变化的时候)
也可以打勾:更新的时候把新加入的资源重新设定到一个组中并打包(适合当包中只有少数资源发生变化的适合)
当我们打勾了,并更新了组中资源的时候,点击这个工具来帮助我们检查
它会提示我们这些东西已经发生了变化,我们点击Apply
他就会自动帮助我们把这些更新了的资源移动到另一个组中了。之后再需要相同的资源的时候,也会优先在更新的组中查找
总体来说,还是根据更新的频率与规模来选择合适的更新限制
四.其他注意事项
①资源打包是指把可寻址资源按照分配好的组和设定去打成一个或者多个AB包,并且自定义如何存储与加载这些包
②资源打包的配置我们可以把每组规定为都打成一个包,按类型打包,或者按标签打包
③资源打包的注意事项有
- ·要注意场景资源无论如何都会单独打成一个场景包
- ·两个不同包中的资源分别都依赖于同一个资源的时候,建议把这个资源打成一个第三方的包,这样就可以避免它自动帮我们把这个资源同时放进两个包中浪费空间。尤其是对图集而言的时候,建议把图集都单独打成一个组
- ·建议对各个类型都单独设定一个组进行打包;但是注意一组中不能有太多资源,也尽量不要有太多的组,要找到这两者之间的一个平衡的状态
五.总结
①可以通过静态方法来更灵活地通过资源名字与标签读取一个或者多个资源。并在其回调事件中获取相应的资源。同时注意对加载句柄在合适的地方进行统一管理与释放
②打包与加载资源的时候的位置是由概述文件,可寻址设置配置文件,组配置文件来决定的。打包到本地的AB包使用默认路径的情况下会把它们再移动到Streaming Assets下。
③远端加载的是服务器的资源,我们可以随时更新服务器的资源而不用重新构建整个项目