Unity Addressable 快速使用
说明:下文中Addressable简称Aa
使用Aa的原因
- 使用Aa可以做到动态加载,这里的动态加载指的是当我们需要某个资源的时候才去加载它。这里的资源可以是预制体、图片、音效等等。
这样做的好处是: 避免资源全部一次性加载,占用不必要的内存,避免手机资源加载缓慢、手机发热,卡顿。 - 可以做到资源的热更,注意这里的资源不包括代码。这部分后面再细说。
安装Aa
.CN后缀的是加密版本,但是好像有看到文章说有大量GC存在,还没查验过。
这里先使用没有后缀版本的。
使用Aa
1. 创建Aa
2. 添加需要动态加载的资源
方法1: 选中资源,在Inspector中勾选Aa
方法2: 选中资源,直接拖拽到Aa面板中
注意事项
添加了需要动态加载的资源之后,可以右键简化名称,这里的名称是下面代码中所需要的参数。
3. 使用代码加载
方法一:
//使用LoadAssetAsync方法Addressables.LoadAssetAsync<GameObject>("Alpha@Alpha").Completed += (handle) =>{// 预设物体GameObject result = handle.Result;// 实例化GameObject alpha = Instantiate(result);alpha.transform.position = new Vector3(-4, 0, 0);};//使用InstantiateAsync方法Addressables.InstantiateAsync("Alpha@Alpha").Completed += (handle) =>{// 已实例化的物体GameObject alpha = handle.Result;alpha.transform.position = new Vector3(-2, 0, 0);};
LoadAssetAsync和InstantiateAsync 都可以使用加载Aa资源。两者的区别是,InstantiateAsync直接帮你实例化了,省去了LoadAssetAsync中的Instantiate过程。
方法二
使用async、await的方法
private async void InstantiateBetaObj(){//使用LoadAssetAsync方法GameObject betaPrefabObj = await Addressables.LoadAssetAsync<GameObject>("Beta@Beta").Task;GameObject betaObj1 = Instantiate(betaPrefabObj);betaObj1.transform.position = new Vector3(2, 0, 0);//使用InstantiateAsync方法GameObject betaObj2 = await Addressables.InstantiateAsync("Beta@Beta").Task;betaObj2.transform.position = new Vector3(4, 0, 0);}
注意: 测试的时候需要加上函数头中的async,别只复制了函数体内的内容。
方法三
声明AssetReference类型,AssetReference类型是弱引用类型,是不会打进包体中。如果声明GameObject类型就会打进包体中。
//先声明类型public AssetReference newPrefabRef;
newPrefabRef.LoadAssetAsync<GameObject>().Completed += (obj) =>{// 预设GameObject result = obj.Result;// 实例化GameObject newPreObj = Instantiate(result);newPreObj.transform.position = new Vector3(0.9f, 0, 0);};newPrefabRef.InstantiateAsync().Completed += (obj) =>{// 已实例化的物体GameObject newPreObj = obj.Result;newPreObj.transform.position = new Vector3(-0.9f, 0, 0);};
这里我们是使用声明的类型的LoadAssetAsync ,InstantiateAsync 的来创建的。
至此,Aa的简单使用过程就介绍完了。下面介绍其他内容。
Aa的加载方式
Use Asset Database: 不需要 Build 打Addressable资源包就可以使用代码加载(开发中选择这个就可以了)。
Simulate Groups (advanced): 不需要 Build 打Addressable资源包就可以使用代码加载。 但是可以模拟Aa的加载,并统计分析数据,方便我们进行快速分析(详细步骤在下面)。
Use Exising Build: 需要先执行Build打出Addressable资源包,它会根据Load Path去加载真正的AssetBundle文件并读取资源。如果不先Build,运行时会报错。同样也可以使用分析器看到资源的依赖,引用计数。
查看统计引用
- 勾选AddressableAssetSetting中的Send Profiler Events
- 打开窗口
构建包体外的Aa
我们也可以构建在包体外的Aa资源,通过网络加载资源包。
创建分组
将创建出来的分组选中右键之后,可以改名。我这里便是改成RemoteAssets。
指定包外Aa的BuildPath和LoadPath
找到如下图中路径,选中与上一步创建的同名配置文件,在Inspector中修改BuildPaht,LoadPath为RemoteBuildPath,RemoteLoadPath。
(路径中的AddressableAssetsData是安装Aa之后就会创建的)
修改BuildPath和LoadPaht的具体路径
注意这里与上面内容的区别。上面的内容是指定Aa的路径是本地还是远程。
而这里的内容是修改本地或远程的具体路径。打开方式如下所示:
这里我们就使用真实的环境测试了,而不是用Addressable提供的Hosting。
到这里的时候,我们尝试Build下
构建成功之后可以看到项目路径下多了个ServerData文件夹,里面的内容就是我们创建的包体外的资源。
开始测试
现在让我们来测试一下!
首先我们需要把Play Mode Script 修改为 Use Existing Build 模式。
这里改为UseExisting Build 模式是为了模拟真实的环境,如果选为另外两个模式,我们都不需要把资源放到服务器上就可以运行成功了,所以测试是不准确的。
当然我们这里只是为了测试下通过网络加载是否能加载到我们需要的Aa资源。实际开发中不需要修改为Use Exiting Build模式。
代码部分
无论这个Aa资源是在包外的还是在包内的,加载方式都是一样的。
- 我们创建个空的RawImage对象
- 引用RawImage对象
public RawImage headIcon;
- 加载图片,赋值给RawImage
Addressables.LoadAssetAsync<Texture2D>("pansen").Completed += (obj) =>{// 图片Texture2D tex2D = obj.Result;headIcon.texture = tex2D;headIcon.GetComponent<RectTransform>().sizeDelta = new Vector2(tex2D.width, tex2D.height);};
将我们之前创建的Aa资源放到服务器
将我们上面创建的ServerData/StandaloneWindows64下的资源放到服务器上。这里就不演示了。
开始运行
点击play之后,就可以看到效果了。
测试
现在我想知道,这个资源是否就是从网络上下载的呢?
- 我们先把服务器上的资源删除。
- 删除缓存在本地的资源。使用Everything工具搜索Aa资源的hash值,注意是搜索hash值,不要搜索整个Aa资源的名字,那样会搜索不到缓存在我们电脑上的资源。
- 把构建在本地的Aa资源删除,也就是ServerData/StandaloneWindows64 下的资源
现在我们再运行下试试。发现会报如下错误:
颗粒细度修改
我们Build的时候默认按Group为颗粒进行打包,如果我们想修改成以单个文件为颗粒改怎么做?
我们先在RemoteAssets中再添加一张图片,然后Build下。
可以看到只有一个.bundle文件。
以单个文件为颗粒细度
选择远端的配置文件,在Inspector中修改Bundle Mode为Pack Separately即可
我们再尝试Build下:
可以看到输出了两个.bundle。分别对应每个图片资源。
以Label标签为颗粒细度
上面的颗粒细度太细了,有时候我们不想分的这么细。此时我们可以使用以Label为颗粒细度。
新建标签
- 打开窗口
- 添加标签。按加号即可添加,这里我添加了两个:Audio,Texture。
设置标签
我们给RemoteAssets添加一个声音资源,并给所有的资源设置标签。如下所示:
修改打包方式
选中我们的远端资源配置文件,在Inspector中修改Bundle Mode为Pack Together By Label即可
结果
Build之后,可以看到以Label为细度的.bundle。
一个资源多个Label标签
我们也可以给一个资源打上多个标签,如下:
Build之后的结果如下:
注意:上面结果中,中间这个.bundle里面只有"pansen"这张图片,最后的texture名的.bundle里面只有“gouxiong”这张图片。也就是说,虽然我们给两张图片都设置了“Textrue”这个Label,但是构建的时候不会包含对方。
使用代码加载同个Label标签资源
虽然上面打包的时候,含有texture标签两个资源被分别打包了。但是我们这里获取到的是只要含有同个标签的都会被加载到。
- 声明AssetLabelReference类型
public AssetLabelReference textureLabel;
设置为Texture标签
代码获取
//加载同个Label标签资源Addressables.LoadAssetsAsync<Texture2D>(textureLabel, (texture) =>{Debug.Log("加载资源: " + texture.name);});
- 结果
pansen和gouxiong 都输出了。
热更新资源
现在我需要把下图中框中的头像替换一个
换成下面这个:
开启Build Remote Catalog
如下所示,选择AddressableAssetSettings,勾选Build Remote Catalog。选择BuildPath和LocalPath指定的值。
重新构建
重新Build之后,可以看到输出目录多了以catalog开头的.hash和.json文件。这两个文件是在我们上面勾选了Build Remote Catalog之后才会出现的。
为了测试的时候方便,我这里的RemoteAssets下只有一张"pansen"的图片,所以只有一个.bundle文件。
注意事项
注意,如果需要热更资源,那么确保被替换的资源有catalog的两个文件。也就是说如果我一开始没有勾选Build Remote Catalog,然后Build。这个时候远程动态加载图片是没问题的,但是热更替换图片就不行了,因为我们需要对catalog的两个文件进行比较。接着往下看。
测试资源加载
把上面构建的文件拖到服务器上。然后使用代码测试是否能正常加载。代码还是使用上面的,不再累述:
public RawImage headIcon;
Addressables.LoadAssetAsync<Texture2D>("pansen").Completed += (obj) =>{// 图片Texture2D tex2D = obj.Result;headIcon.texture = tex2D;headIcon.GetComponent<RectTransform>().sizeDelta = new Vector2(tex2D.width, tex2D.height);};
结果如下,到这里说明我们加载成功了:
替换资源
把之前使用的"pansen"资源替换成下面的
构建: Update a Previous Build
注意这里不是我们上面经常使用的 Build – New Build – Defaule Build Script了,而是使用下面这个:
点击之后会弹出一个文件框,让你选择.bin文件。因为我是在电脑上测试,所以选择window。
Step1:
Step2:
双击选中.bin文件之后。会在BuildPaht中出现新的.bundle,以及被修改的catalog的两个文件。
测试
注意这里需要把被修改的catalog的两个文件,以及新增的.bundle文件上传。只上传.bundle是不会生效的。
重新运行效果如下:
如果你的结果没有变化,可能是本地文件缓存的原因。根据上文使用Everything查找缓存的方法,删除之前的缓存。同时也把ServerData/StandaloneWindow下之前的.bundle删除。
Aa资源释放
加载代码:
Addressables.LoadAssetAsync<Texture2D>("pansen").Completed += (obj) =>{// 图片tex2D = obj.Result;headIcon.texture = tex2D;headIcon.GetComponent<RectTransform>().sizeDelta = new Vector2(tex2D.width, tex2D.height);};
释放代码:
注意需要使用Addressables.Release。
public void ReleaseAaAsset(){//释放资源if (tex2D != null){Addressables.Release(tex2D);}//销毁RawImageDestroy(headIcon.gameObject);}
可以打开EventViewr查看变化:
释放前:
释放后:
释放后已经没有了"pansen"的资源了。
文章内容参考:link
Unity Addressable 快速使用相关推荐
- Unity Addressable学习笔记一(整体介绍)
Unity Addressable 基本介绍 版本 当前使用版本 1.8.5 下载 点击打开后是下面这个界面 1.Create: 创建一个新的asset groups 2.Profile: Profi ...
- Unity editor 快速上手 quick start
Unity editor 快速上手 quick start Warning:非干货,是比较个人向的快速上手的代码例子,不一定是最好的方法,但能work. 主要目的是做一个可以动态添加和移除新的行的自定 ...
- Unity材质快速复制
做3D方面的同学们不知道是否会频繁碰见这样的问题: 1.美术给的模型或者动画的材质因为第三方渲染器的原因导入unity后就只剩下无贴图的原始材质球,只好苦逼的一个个上贴图材质,上了一个也就罢了,后面的 ...
- 【游戏开发教程】Unity Cinemachine快速上手,详细案例讲解(虚拟相机系统 | 新发出品 | 良心教程)
文章目录 一.前言 二.插件下载 三.案例1:第三人称自由视角,Free Look character场景 1.场景演示 2.组件参数 2.1.CinemachineBrain:核心 2.2.Cine ...
- 【游戏开发教程】Unity Cinemachine快速上手,详细案例讲解(虚拟相机系统 新发出品 良心教程)
文章目录 一.前言 二.插件下载 三.案例1:第三人称自由视角,Free Look character场景 1.场景演示 2.组件参数 2.1.CinemachineBrain:核心 2.2.Cine ...
- 【unity】快速了解游戏制作流程-制作九宫格简单游戏demo
前言 hi~大家好呀!欢迎来到我的unity学习笔记系列~,本篇我会简单的记录一下游戏流程并且简单上手一个通过九宫格移动到指定位置的小游戏,话不多说,我们直接开始吧~ 本篇源自我看B站一位up主的视频 ...
- Unity Addressable内存管理
先看一个真机测试实例: 两个物体放在同一个Group里面 只创建Cube时,内存资源中只有Cube的材质球和贴图 同时创建了Cube和Sphere,内存资源中拥有两个材质球和贴图 此时只删除Cube, ...
- Unity Addressable学习笔记二(Hosting热更新)
上篇大致介绍了Addressables系统中的大部分需要用到的按钮文件配置的作用,本篇就在上一篇介绍的基础上来进行一次实际的资源热更测试.Unity版本2019.3 Addressables版本1.8 ...
- Unity如何快速镜像物体(FBX Exporter Blender)
1.包管理器中安装FBX Exporter,参考: [unity] untiy中如何导出FBX_SunGZ123456的博客-CSDN博客_unity导出fbx 2.由于我用的是Blender,因此F ...
最新文章
- Python处理XML文件
- (仿头条APP项目)3.二级页面首页的ViewPager页面切换
- 为什么判断 n 是否为质数只需除到开平方根就行了?(直接证明)
- Base64Util 用户名和密码Base64编码Java代码
- 虚拟机下Ubuntu共享主机文件(Ubuntu、VMware、共享) .
- 打印user webclient ui浏览历史的工具
- 【OpenCV函数】轮廓提取;轮廓绘制;轮廓面积;外接矩形
- 基于微信小程序的比赛报名系统
- Tampermonkey油猴教程及Greasyfork脚本使用
- 新一配:为什么现在都找不到破解软件了?
- 电脑数据恢复软件推荐10款
- Reflection probes
- atomic 原子操作
- 代理服务器使用全攻略(转)
- Python3之基础语法
- 华为鸿蒙系统手机上市,6月2日华为要有大动作,不仅有鸿蒙系统,P50发布时间也将公布...
- 简单静态web页面+动画(小案例)
- Java学习笔记(视频:韩顺平老师)1.0
- Zhong__Python math
- 关于RAID1的读写问题