Addressable 寻址

Addressable

1、什么是Addressable(可寻址资产)系统
可寻址资产系统提供了一种通过“地址”加载资产的简便方法。它通过简化内容包的创建和部署来处理资产管理开销。可寻址资产系统使用异步加载来支持从任何位置加载任何依赖项集合。
一旦资产被标记为“可寻址”,就可以从任何地方调用可寻址资产。无论该可寻址资产是驻留在本地播放器还是内容传送网络上,系统都将找到并返回它。您可以通过其地址加载单个可寻址,或使用您定义的自定义组标签加载许多可寻址。
2、为什么要推出Addressable系统
迭代时间:通过其地址引用内容是超级高效的。使用地址引用,只会检索内容。对内容的优化不再需要更改代码。
依赖关系管理:系统不仅返回地址的内容,还返回该内容的所有依赖关系。系统会在整个资产准备就绪时通知您,因此在返回内容之前会加载所有网格,着色器,动画等。
内存管理:该地址不仅可以加载资产,还可以卸载它们。引用会自动计算,强大的分析器可帮助您发现潜在的内存问题。
内容打包:由于系统映射并理解复杂的依赖关系链,因此即使在移动或重命名资产时,它也可以有效地打包捆绑包。可以为本地和远程部署轻松准备资产,以支持可下载内容(DLC)和减少应用程序大小。
3、Addressable系统对比AssetBundle有什么区别
我初步学习了可寻址系统后,也算是对它有了一个了解。
Addressable Assets System 是由 Addressables和ResourceManager组成的系统!Addressables和ResourceManager位于不同的包中
Addressables 依赖于 ResourceManager
在PackageManager中引入Addressables时,ResourceManager会自动包含
全部用C#编写
ResourceManager是一个用于正确管理资源加载和卸载的框架
使用引用计数执行卸载管理
DI可以定制加载过程等
它具有方便的功能,例如显示资源加载情况的分析器
可寻址资源系统与AssetBundle的区别
1.可寻址资源系统只需要一个资源的地址就可以从任意地方进行加载,而AssetBundle需要从制定bundle中加载资源。
2.可寻址资源系统加载到内存中的bundle有引用计数,而AssetBundle加载到内存中的bundle需要自己进行管理。
3.可寻址资源系统会自己管理依赖关系,而AssetBundle需要自己管理依赖关系,维护起来比较困难。
4.可寻址资源系统默认的所有加载操作都是异步操作,可以添加事件监听,而AssetBundle则有同步和异步加载。
4、Addressable系统怎么使用
打包
把资源加入到group中,才算是把这个资源加入到了AA系统当中,这时候才能对资源进行打包.AA系统还是会把资源打包成我们熟悉的AssetsBundle包,一个group中的资源,我们可以配置group来决定打包粒度
加载
AA系统的运行方式是通过我们给资源设置的key,来加载资源,并且帮助我们管理资源的引用,更新.只要预先设置好资源的配置,那我们在代码里面加载的时候,完全不用考虑其它的,只管直接使用就行.
更新
主要通过catalog文件来判断当前缓存的资源是否过期,如果过期,则会去对应的地址上更新资源,这个文件里记录了AB包的hash值,对应的远程更新地址.所以在更新资源之前,会首先更新catalog文件,再根据catalog文件来判定当前本地缓存的资源是否过期.

首先通过PackageManager安装AA斜体样式> 在这里插入图片描述

基本介绍
AddressableAssetSettings
AA系统的基本配置,我们初级使用的话只需要用到几个变量
Disable Catalog Update On Startup
默认是没有勾选的,没有勾选,那么每次AA系统初始化的时候,会自动更新catalog文件,勾选上,将不会自动更新catalog文件,也就意味着不会自动更新资源.AA系统的初始化会在任意接口第一次调用时初始化,也可以主动调用Addressables.InitializeAsync()初始化.
Build Remote Catalog
默认没有勾选,只有勾选上才会创建catalog在指定目录,以后客户端才可以下载这个catalog来进行对比更新.
Build Path
资源打包后存放的地址,用于HostingService的资源存放地址
Load Path
资源加载地址,用于客户端加载远程资源的地址.
Send Profiler Events
调试用,允许加载资源的时候发送事件给EventViewer,可以通过这个工具查看资源的使用情况
Log Runtime Exception
输出加载资源时的异常,开启时如果资源加载发生异常,会直接抛出.如果关闭,我们也可以通过加载资源时返回的句柄,来获取到异常信息.同时我们也可以给项目添加宏ADDRESSABLES_LOG_ALL,来查看更多的日志信息。
在这里插入图片描述
Group
Group是用于整合资源的.我们通过把资源添加进Group,来使资源加入AA系统的管理.我们可以通过配置,来设置资源的打包粒度,位置.没有加入Group的资源,将无法使用AA系统来打包,加载.
安装AA系统后,默认会有两个Group.Built In Data里面包含一些内置资源,我们无法配置,也无法往里面添加删除资源,这个Group我们可以不用管它.
Default Local Group就是常规的Group了,我们可以对它进行配置以及添加删除资源.也可以给这个Group重命名.
在这里插入图片描述
Group Schema
这个可以理解为Group的配置,系统预先设置3种配置.可以对每个常规Group添加或删除Schema
Content Packing & Loading(BundledAssetGroupSchema)
这个配置用于配置打包信息,告诉AA系统,这个Group将如何打包,打包粒度,以及打出来的AB包存放在哪个位置,还有就是这个包里面的资源,应该在哪里加载,最终打包后,这个Group的位置信息,加载地址,还会被catalog记录.
– Build And Load Paths: 决定AB包的存放位置和加载位置
– Compression: AB包的压缩方式
– Include In Build: 默认勾选的,只有勾选上才会进行打包
– BundleMode: AB包打包粒度,有三种选项,PackTogether是把整个Group中的资源打包成一个AB包,PackSeparately是每个资源分别打包为AB包,PackTogetherByLabel是根据标签来决定哪些资源应该打成一个AB包.
Content Update Restriction(ContentUpdateGroupSchema)
这个配置只有两个选项,用于表示这个包是静态的还是非静态的,
–Can Chang Post Release: 非静态包,可以在AB包发布后,被修改.
–Cannot Chang Post Release: 静态包,AB包在发布后不能再被修改.
Resources and Built In Scenes(PlayerDataGroupSchema)
这个配置只有两个变量,一般不太会使用这个配置,所以默认都只会添加前面两个Schema
–Include Resources Folders: 是否包含Resources文件夹中的资源,这个文件夹是Unity的一个特殊的文件夹,在这个文件夹下的资源在发布时都会包含在包体中,所以一般我们是不会包含这个文件夹中的资源的.
–Include Build Settings Scenes: 是否包含Build Setting 中拖入的场景,一般情况下我们可以直接把场景拖入到Group中,没必要使用这个选项来自动包含,反而不直观。
在这里插入图片描述
Profile
Profile的作用主要是用于指定几个项目中需要用到的地址.我们可以在这个窗口中点击Create->Profile创建Profile,每个Profile中都包含4个默认的变量,我们也可以点击Create->Variable扩展变量.
语法
可以直接填入目录地址,比如/usr/data/aa/,同时也支持两种特殊语法 [] 中括号和 {} 花括号.
中括号: 可以包含生成时就有的变量,比如UnityEditor.EditorUserBuildSettings.activeBuildTarget.这个是在程序发布时,编辑器就已经有的变量,
花括号: 可以包含运行时的变量,比如UnityEngine.AddressableAssets.Addressables.RuntimePath,这个变量是需要程序运行时获取的变量,可能会根据你的平台不同而变化.也可以自定义一个运行时变量.
变量
变量本身的意义在于你使用在什么地方,下面几个默认变量,根据它的名字,我们可以给它固定的意义,不要交叉使用,不然后面管理会很混乱.
BuildTarget: 发布平台,可以根据[UnityEditor.EditorUserBuildSettings.activeBuildTarget]得到当前编辑器激活的平台,当然也可以指定一个固定平台比如[UnityEditor.BuildTarget.Android]
LocalBuildPath: 打包本地资源时的存放路径,资源可以分为本地资源和远程资源,本地资源是发布时带进包体的,远程资源会放在资源服务器上,在使用时下载.这个路径Unity的默认值是[UnityEngine.AddressableAssets.Addressables.BuildPath]/[BuildTarget],它的实际位置是在项目中Library/com.unity.addressables/StreamingAssetsCopy/aa/当前平台.
建议不要随意修改这个变量,因为这个地址里面的内容是会在打包时拷贝进入StreamingAssets文件夹,如果修改为其它地址,Unity打包的时候是不会自动拷贝进去的.
LocalLoadPath: 本地资源加载地址,默认值是{UnityEngine.AddressableAssets.Addressables.RuntimePath}/[BuildTarget],这是个运行时的变量,发布过后,这就是StreamingAssets目录的地址.
RemoteBuildPath 远程资源的存放地址
RemoteLoadPath 远程资源的加载地址:比如http://[PrivateIpAddress]:[HostingServicePort],这里使用了两个变量,这两个变量是HostingService提供的。
在这里插入图片描述

1.Addressable Assets 窗口
第一次打开" Window -> Asset Management -> Addressable Assets "会需要新建一个Addressable 设置,默认资源分为两组Build In Data,Default Local Group。前者不能改动,而后者我们可以在组里进行添加和删除。我们也可以通过在Addressable Assets窗口右键再选中Create New Group-> Packed Assets来新建组。
在这里插入图片描述
2.标记资源
通过勾选预设/声音等资源为可寻址资源。
在这里插入图片描述
然后在Addressable Assets面板上就会有它选中后的状态。
在这里插入图片描述
3.加载资源
在我们添加好可寻址资源后,就可以在代码中通过可寻址资源的地址来加载资源了。可寻址资源有3个模式可选择
在这里插入图片描述
Fast Mode: 快速模式:直接加载文件而不打包,快速但Profiler获取的信息较少;在此模式下,我们使用 AssetDatabase.LoadAssetAtPath 直接加载文件。虽然AssetBundle构建可以不要求立即执行的,它不能在探查证实,如果他们被列入其中AssetBundle资产。 Virtual Mode:虚拟模式:在不打包的情况下模拟靠近AssetBundle的操作;与FastMode不同,您可以查看哪个AssetBundle包含资产。此模式最终还加载了AssetDatabase.LoadAssetAtPath 。虽然AssetBundle构建是没有必要的,第一为了构建AssetBundle和资产之间的对应关系。还可以通过设置虚拟通信速度来模拟加载时间。Packed Mode:打包模式:实际上是从AssetBundle打包和加载;在这种模式下,实际构建并加载AssetBundle。
通过key加载
我们可以直接通过 Addressables类的LoadAssetAsync接口来加载资源,参数为可寻址资源的地址。通过监听事件,在加载完成后完成实例化。
Addressables.InstantiateAsync(“Cube”);
我们也可以直接通过Addressables类的InstantiateAsync接口来直接实例化资源。

void Start()
{
hand = Addressables.LoadAssetAsync<GameObject>("Cube");
hand.Completed += OnResLoadedHandler;
}private void OnResLoadedHandler(AsyncOperationHandle<GameObject> obj)
{
GameObject go = obj.Result;
Instantiate(go);
}

通过AssetReference加载
该AssetReference类提供了一个机制来访问的资产,而不需要知道的字符串(或其他方式)的地址。
要使用*AssetReference 类访问可寻址资产:
我们在继承自monobehaviour的脚步中添加一个成员:
public AssetReference ar;
然后在该脚本组件的视图中就可以选择可寻址资产了

 public AssetReference box;
       void LoadBox()
    {
        box.LoadAssetAsync<GameObject>().Completed += OnLoaded;
    }
    void OnLoaded(AsyncOperationHandle<GameObject> obj)
    {
        GameObject cube = obj.Result;
    }

4.可寻址资产系统的加载
游戏对象实例化要加载,使用Addressables.InstantiateAsync。这将实例化传入指定的预制件location。Addressables将加载Prefab及其依赖项,在该加载期间递增所有项的引用计数。InstantiateAsync在同一地址上调用三次将导致所有依赖资产的ref-count为3。LoadAssetAsync调用三次则不同,每次InstantiateAsync呼叫都会AsyncOperationHandle指向一个独特的操作。这是因为每个结果InstantiateAsync都是一个唯一的实例。InstantiateAsync和其他加载调用之间的另一个区别是可选参数trackHandle。如果将其设置为false,则必须保留AsyncOperationHandle在发布实例期间使用它。这样更有效,但需要游戏开发人员付出更多努力。
游戏对象实例化要卸载,使用Addressables.ReleaseInstance或关闭实例化对象所在的场景。此场景可能已加载(因此已关闭)Additive或Single模式。此场景也可以通过Addressables或SceneManagement加载。如上所述,如果设置trackHandle为false,则只能Addressables.ReleaseInstance使用句柄调用,而不能使用实际的GameObject 调用。
关于以下内容的注释Addressables.ReleaseInstance:如果您调用Addressables.ReleaseInstance的是未通过可寻址创建的实例,或者使用trackHandle = false创建的实例,我们会检测Addressables.ReleaseInstance到该实例并返回false以指示它无法释放传递给它的实例。
Addressables.InstantiateAsync有一些与之相关的开销,所以如果你需要每帧100次实例化相同的对象,你应该考虑通过Addressables加载,然后实例化外部的Addressables。在这种情况下,您可以调用Addressables.LoadAssetAsync,然后保存结果,并调用GameObject.Instantiate()该结果。这使您可以灵活地以同步方式调用Instantiate。缺点是我们不知道你创建了多少个实例。如果你打电话时还有漂浮的实例Addressables.Release,你可能会陷入糟糕的境地。例如,引用纹理的预制件将不再具有要引用的有效(加载)纹理,从而导致渲染问题(或更糟)。由于我们可能无法立即触发内存卸载(请参阅下面的“清除内存时”),因此很难跟踪这些类型的问题。

void LoadBoxName()
    {
         //不直接生成,在回调中处理生成问题
        Addressables.LoadAssetAsync<GameObject>("cube").Completed += OnLoaded;     
    }     
	  void OnLoadedName(AsyncOperationHandle<GameObject> obj)
    {
        GameObject cube = obj.Result;   
	 }
	public void LocalStatic()
    {
        //通过地址查询资源,并直接生成
        Addressables.InstantiateAsync("Cube").Completed += ObjectLoadDone;      
    }
    private void ObjectLoadDone(AsyncOperationHandle<GameObject> obj)
    {
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
          
        }
    }

在这里插入图片描述
在这里插入图片描述
Unity Addressables加载资源方式汇总
Unity官方:
如果同时将Sprite Atlas和源Sprite
Textures标记为可寻址,则最终的AssetBundle将包含重复的数据。有一个Addressables
Analyze规则可以检测到这一点。在这种情况下,我们建议仅将Sprite Atlas标记为可寻址。
在这里插入图片描述
加载场景

public AssetReference Scene;

 //加载场景
Scene.LoadSceneAsync().Completed += SceneLoaded;
private void SceneLoaded(AsyncOperationHandle<SceneInstance> obj)
{
    switch (obj.Status)
    {
        case AsyncOperationStatus.None:
            break;
        case AsyncOperationStatus.Succeeded:
            Scene.LoadSceneAsync(UnityEngine.SceneManagement.LoadSceneMode.Additive);
            break;
        case AsyncOperationStatus.Failed:
            break;
    }
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值