Addressables概述

1.Addressables说明:Addressables是基于AssetBundle架构做的高阶流程,目的是实现资源自动化管理,Addressables翻译过来是可寻址的意思,它是可寻址资源管理系统,是Unity从2018.2版本开始,建议用于替代AssetBundle的高阶资源管理系统,在之后的Unity的新版本中,AssetBundle将渐渐被淘汰;

2.Addressables的优点:

  • 自动化管理AB包打包、发布、加载;
  • 可以更方便的进行本地、远程资源的加载;
  • 系统会自动处理资源关联性;
  • 内存管理更方便;
  • 迭代更方便;

3.Addressables使用方法:

  • 导入包:在Package Manager中导入该包;
  • 创建配置文件:在Window找到Addressables中的Groups点击创建配置文件,或者直接在Inspector窗口勾选Addressable就会自动创建;

资源加载基础

寻址资源设置

1.让资源变为可寻址资源:
        //方法一:选中资源,勾选Inspector窗口中的Addressable
        //方法二:选中资源,拖入Addressables Groups窗口中

        //注意:
        //1.C#代码无法作为可寻址资源
        //2.Resources文件夹下资源如果变为寻址资源,会移入Resources_moved文件夹中
        //  原因:Resources文件夹下资源会最终打包出去,如果变为可寻址资源意味着想通过Addressables进行管理
        //  那么它就没有必要通过Resources方式去加载和打包,所以会自动迁移,避免重复打包,浪费空间

        //3.右键选择资源时菜单内容
        //Move Addressables to Group:将该资源放入到现有的另一个组中
        //Move Addressables to New Gourp:使用与当前组相同设置创建一个新租,并将该资源放入该新组中
        //Rmove Addressables:移除资源,该资源会变为不可寻址资源
        //Simplify Addressable Names:简化可寻址资源名,会删除名称中的路径和拓展,简化缩短名称
        //Copy Address to Clipboard:将地址复制到剪贴板
        //Change Address:改名
        //Create New Group:创建新租

2.资源组窗口讲解:
(1).资源信息(关键)
        //1.GroupName\Addressable Name:分组名\可寻址名(可重名,描述资源)
        //2.Path:路径(不可重复,资源定位)
        //3.Labels:标签(可重复、可用于区分资源种类,例如青铜装备、黄金装备)

(2).创建分组相关
        //Create——>Group
        //Packed Assets:打包资源分组
        //Blank(no schema):空白(无架构)
        //区别:Packed Assets默认自带默认打包加载相关设置信息,Blank没有相关信息需要自己关联

        //组对于我们来说意义重大,之后在资源打包时,一个组可以作为一个或多个AB包

        //关于组设置相关信息,之后详细讲解

(3).选中某一组后右键
        //Remove Group(s):移除组,组中所有资源恢复为不可寻址资源
        //Simplify Addressable Names:简化可寻址名称,会删除名称中的路径和拓展,简化缩短名称
        //Set as Default:设置为默认组,当直接勾选资源中的Addressable时,会自动加入该组
        //Inspect Group Setting:快速选中关联的组相关配置文件
        //Rename:重命名
        //Create New Group:创建新组

(4).配置概述相关
        //Manage Profiles:管理配置文件
        //可以配置打包目标、本地远程的打包加载路径等等信息(之后再详细讲解)

(5).Tools工具相关
        //Inspect System Settings:检查系统设置
        //Check for content Update Restrictions:检查内容更新限制
        //Window:打开Addressables相关窗口
        //Groups View:分组视图相关
        //  Show Sprite and Subobject Addressable:显示可寻址对象的精灵和子对象,一般想要看到图集资源内内容时可以勾选该选项
        //  Group Hierarchy with Dashes:带破折号的组层次结构

(6).Play Mode Script播放模式脚本(编辑模式下如何运行)
        //确定在编辑器播放模式下运行游戏时,可寻址系统如何访问可寻址资源
        //Use Asset Database(fastest):
        //使用资源数据库(最快的),一般在开发阶段使用,使用此选项时,您不必打包可寻址内容,它会直接使用文件夹中的资源
        //在实际开发时,可以不使用这种模式,这种模式没有测试的意义

        //Simulate Groups(advanced):
        //模拟组(后期),一般在测试阶段使用,分析布局和依赖项的内容,而不创建AB包
        //通过ResourceManager从资产数据库加载资产,就像通过AB包加载一样
        //通过引入时间延迟,模拟远程资产绑定的下载速度和本地绑定的文件加载速度
        //在开发阶段可以使用这个模式来进行资源加载

        //Use Existing Build(requires built groups):
        //正儿八经的从AB包加载资源
        //使用现有AB包(需要构建AB包),一般在最终发布测试阶段使用
        //从早期内容版本创建的AB包加载资产
        //在使用此选项之前,必须使用生成脚本(如默认生成脚本)打包资源
        //远程内容必须托管在用于生成内容的配置文件的RemoteLoadPath上

(7).Build(构建打包相关)
        //New Build:构建AB包资源(相当于打包资源分组)
        //Update a Previour Build:更新以前的版本
        //Clean Build:清空之前的构建资源

3.资源名注意事项:
        //1.资源路径一定不允许相同(后缀不同,名字相同可以)
        //2.资源名我们可以随意修改
        //3.之后在加载资源时我们可以使用名字和标签作为双标识加载指定资源
        //4.我们可以按规则将资源进行分组,比如:角色、装备、怪物、UI等等

指定资源加载(不常用)

1.Addressables中的资源标识类
        //AssetReference                通用资源标识类 可以用来加载任意类型资源
        //AssetReferenceAtlasedSprite   图集资源标识类
        //AssetReferenceGameObject      游戏对象资源标识类
        //AssetReferenceSprite          精灵图片资源标识类
        //AssetReferenceTexture         贴图资源标识类
        //AssetReferenceTexture2D
        //AssetReferenceTexture3D
        //AssetReferenceT<>             指定类型标识类

        //通过不同类型标识类对象的申明 我们可以在Inspector窗口中筛选关联的资源对象

2.加载资源
        //注意:所有Addressables加载相关都使用异步加载
        //需要引用命名空间:using UnityEngine.ResourceManagement.AsyncOperations;
        //AsyncOperationHandle<GameObject> handle = assetReference.LoadAssetAsync<GameObject>();
        //加载成功后使用
        //1.通过事件函数传入的参数判断加载是否成功 并且创建
        //2.通过资源标识类对象判断 并且创建

        //一步到位,通过异步加载返回值 对完成进行事件监听
        assetReference.LoadAssetAsync<GameObject>().Completed += (handle) =>
        {
            //使用传入的参数(建议)
            //判断是否加载成功
            if (handle.Status == AsyncOperationStatus.Succeeded)
            {
                GameObject cube = Instantiate(handle.Result);
                //一定资源加载过后 使用完后 再去释放
                assetReference.ReleaseAsset();
            }
           
            //使用标识类创建,现在不推荐
            //if(assetReference.IsDone)Instantiate(assetReference.Asset);
        };

3.加载场景
        sceneReference.LoadSceneAsync().Completed += (handle) =>
        {
            //初始化场景的一些信息,和资源加载相同
            print("场景加载结束");
        };

4.释放资源
        //释放资源相关API
        //ReleaseAsset
        //写在外部是不合理的,一般写在加载字资源后
        //assetReference.ReleaseAsset();
        //1.释放资源方法后,资源标识类中的资源会置空,但是AsyncOperationHandle类中的对象不为空
        //2.释放资源不会影响场景中被实例化出来的对象,但是会影响使用的资源,例如贴图等,和AssetBundle是一样的;
        
5.直接实例化对象
        //只适用于 想要实例化的 对象 才会直接使用该方法 一般都是GameObject预设体
        gameobjcetReference.InstantiateAsync();
        
6.自定义标识类
        //自定义类 继承AssetReferenceT<Material>类 即可自定义一个指定类型的标识类
        //该功能主要用于Unity2020.1之前,因为之前的版本不能直接使用AssetReferenceT泛型字段

Label标签

1.Label标签的作用:可以在寻址资源设置中,为相同作用的资源(模型、贴图、材质、UI等),我们可以让他们的资源名相同,通过标签Label区分他们来加载使用;

2.Label标签特性约束:通过特性[AssetReferenceUILabelRestriction()]来约束资源,里面可以填多个标签名;

动态加载资源

1.通过资源名或标签名动态加载单个资源
        //命名空间:
        //UnityEngine.AddressableAssets 和 UnityEngine.ResourceManagement.AsyncOperations
        
        //参数名可以是资源名也可以是标签名
        Addressables.LoadAssetAsync<GameObject>("Red").Completed += (handle) =>
        {
            //判断加载成功
            if (handle.Status == AsyncOperationStatus.Succeeded)
                Instantiate(handle.Result);
            //一定要是 加载完成后 使用完毕后 再去释放
            //需要指定要释放哪一个返回值,不管任何资源 只要释放后 都会影响之前在使用该资源的对象
            Addressables.Release(handle);
        };

        //注意:
        //1.如果存在同名或同标签的同类型资源,我们无法确定加载的哪一个,它会自动加载找到的第一个满足条件的对象
        //2.如果存在同名或同标签的不同类型资源,我们可以根据泛型类型来决定加载哪一个


2.根据资源名或标签名加载多个对象
        //加载资源
        //参数一:资源名或标签名
        //参数二:加载结束后的回调函数
        //参数三:如果为true表示当资源加载失败时,会自动将已加载的资源和依赖都释放掉;如果为false,需要自己手动来管理释放
        AsyncOperationHandle<IList<Object>> handle = Addressables.LoadAssetsAsync<Object>("Red", (obj) =>
        {
            //释放资源
            Addressables.Release(obj);
        });


3.根据多种信息加载对象
        //参数一:想要加载资源的条件列表(资源名、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);


4.动态加载场景
        //参数一:场景名
        //参数二:加载模式 (叠加还是单独,叠加就是两个场景一起显示,单独就是只保留新加载的场景,正常情况为单独)
        //参数三:场景加载是否激活,如果为false,加载完成后不会直接切换,需要自己使用返回值中的ActivateAsync方法
        //参数四:场景加载的异步操作优先级
        Addressables.LoadSceneAsync("SampleScene", UnityEngine.SceneManagement.LoadSceneMode.Single, false).Completed += (obj)=> {
            //比如说 手动激活场景
            obj.Result.ActivateAsync().completed += (a) =>
            {
                //然后再去创建场景上的对象

                //然后再去隐藏 加载界面

                //注意:场景资源也是可以释放的,并不会影响当前已经加载出来的场景,因为场景的本质只是配置文件
                Addressables.Release(obj);
            };
        };

窗口相关

Profile概述配置窗口

1.Profiles窗口打开方式
        //方法一:Window > Asset Management > Addressables > Profiles
        //方法二:在AddressableAssetSettings中打开
        //方法三:在Addressables Groups窗口中打开


2.Profiles窗口参数相关
(1).右侧
BuildTarget:构建目标,可以在这里设置是哪个平台,默认是你激活哪个平台就是哪个平台
LocalBuildPath:本地构建路径,默认在项目的Library库文件夹中
LocalLoadPath:本地加载路径,在哪里加载本地已有的资源
RemoteBuildPath:远程构建路径
RemoteLoadPath:远程加载路径,在哪里下载远程内容和目录
(2).左侧
Profile:概述文件
Variable:变量(所有概述文件通用)
Build Load Path Variables:构建加载路径变量(所有概述文件通用)
(3).注意:
1.一般情况下,不要去修改本地构建和加载路径默认值
2.当我们针对不同平台远程分发内容时,通过多个配置文件最方便。如果你想要最终的发布包包含所有内容,那么一个默认配置就够了


3.Profiles变量语法
        //所有的变量类型都是string字符串类型
        //你可以在其中填写一些固定的路径或值来决定路径
        //还可以使用两个语法指示符让原本的静态属性变成动态属性

        //[]:方括号,可以使用它包裹变量,在打包构建时会计算方括号包围的内容
        //比如
        //使用自己的变量[BuildTarget]
        //使用别的脚本中变量[UnityEditor.EditorUserBuildSettings.activeBuildTarget]
        //在打包构建时,会使用方括号内变量对应的字符串拼接到目录中

        //{}:大括号,可以使用它包裹变量,在运行时会计算大括号包围的内容
        //比如
        //使用别的脚本中变量{UnityEngine.AddressableAssets.Addressables.RuntimePath}

        //注意:方括号和大括号中使用的变量一定是静态变量或者属性。名称、类型、命名空间必须匹配
        //比如在运行时 UnityEditor编辑器命名空间下的内容是不能使用的

Addressables Hosting可寻址托管窗口

1.Addressables Hosting可寻址托管窗口的作用
        //一般资源服务器需要将其搭建为http服务器
        //这样才能进行资源的上传和下载
        //而Unity为了简化本地测试的这一过程
        //提供了快捷搭建http服务器的工具
        // Addressables Hosting 窗口
        //通过它我们可以将我们的本机模拟为一台远端服务器来进行远端发布加载测试
        //可以帮助我们快速的进行远程打包下载的相关测试

        //简单理解就是把本机作为一台资源服务器

2.打开可寻址托管窗口
        //方法一:Window > Asset Management > Addressables > Hosting
        //方法二:Addressables Groups窗口中 > Tools > Window > Hosting Services

3.可寻址托管窗口参数
(1).左边区域:
	Local Hosting:本地托管,通过本机模拟加载相关内容
	Custom Service:自定义服务
(2).右边区域:
	Service Name:服务器名称
	Service Type(ID):服务器类型
	Port:端口号(一般不自己设置,避免和其它应用产生冲突)
	Upload Speed(kb/s):上载速度
	Enable:是否启用,启用后会自动分配端口号
	Hosting Service Variables-托管服务变量(IP地址、端口号等,我们可以使用这些变量名来编辑Addressables Profiles中的发布和加载相关路径,如http://[PrivateIpAddress]:[HostingServicePort]/[BuildTarget]):
		Variable Name:变量名
		Value:值

4.注意事项
        //Addressable Hosting窗口创建的本地服务器有时候会失效
        //可以在资料区下载第三方工具 让本机变为一个http服务器 模拟远端加载

事件查看窗口

1.事件查看查看说明
        //使用可寻址事件查看窗口可以监视可寻址资源的资源内存管理
        //该窗口
        //1.显示应用程序何时加载和卸载资源
        //2.显示所有可寻址系统操作的引用计数
        //3.显示应用程序帧率和分配的内存总量近似图
        //我们可以通过它来检查可寻址资源对性能的影响
        //并检查没有释放的资源

2.打开事件查看窗口
        //注意:使用事件查看窗口的前提要打开AddressablesAssetSettings配置文件中的事件发送开关
        //1.Window > Asset Management > Addressables > Event Viewer
        //2.Addressabeles Groups > Window > Event Viewer
        
3.事件查看窗口参数
(1).左上角:
	Clear Event:清楚所有记录的帧,会清空窗口中所有内容;
	Unhide All Hidden Events:显示你隐藏的所有事件内容(当我们右键一个内容隐藏后才会显示该选项);

(2).右上角:
	Frame:显示当前所在帧数;
	左按钮和右按钮:在记录的帧中前后切换查看信息;
	Current:选中当前帧;

(3).中央部分:
	FPS:应用的帧率;
	MonoHeap:正在使用的托管堆内存量;
	Event Counts:事件计数,某一帧中发生的可寻址事件的数量;
	Instantiation Counts:实例化计数,某一帧中Addressables.InstantiateAsync的调用数量;
	线性图标:显示统计的什么时候加载释放资源的信息;
	Event 相关:显示当前帧中发生的可寻址操作的事件;

分析窗口

Analyze tool | Addressables | 1.18.19 (unity.cn)

1.分析窗口说明:
        //分析窗口是一种收集项目可寻址布局信息的工具
        //它是一种信息工具,可以让我们对可寻址文件布局做出更明智的决定

2.打开分析窗口:
        //1.Window > Asset Management > Addressables > Analyze
        //2.Addressabeles Groups > Window > Analyze

3.分析窗口参数说明:
(1).上方三个按钮:
	Analyze Selected Rules:分析选定的规则;
	Clear Selected Rules:清除选定规则;
	Fix Selected Rules:修复选定规则;

(2).下方的内容Analyze Rules(分析规则)
a.Fixable Rules-可修复的规则(提供了分析和修复两种功能的规则出现在这里):
	Check Duplicate Bundle Dependencies:检查重复的AB包依赖项,比如资源a和b,都使用了材质c,a和b是可寻址资源,c不是可寻址资源,a,b分别在两个AB包中,那么这时两个AB包中都会有资源c,这时就可以通过该规则排查出该问题,那么这时我们可以选择自己重新处理后打包,也可以选择修复功能,建议使用自己处理问题,因为某些特殊情况它也会认为有问题,比如,一个FBX中有多个网格信息a,b,这时我们分别把网格a放入包A,网格b放入包B,它也会认为A和B有重复资源,但其实他们并没有重复;

b.Unfixable Rules-不可修复的规则(对于只有分析功能,没有修复功能的规则在这里出现):
	Check Resources to Addressable Duplicate Dependencies:检查可寻址重复依赖项的资源,同时出现在可寻址资源和应用程序构建的资源中,比如一个资源A,它是可寻址资源,但是它同时在Resources、StreamingAssets等特殊文件夹中,最终会被打包出去;
	Check Scene to Addressable Duplicate Dependencies:检查场景到可寻址重复依赖项,同时出现在可寻址资源和某一个场景中,比如一个资源A,它是可寻址资源但是它有直接出现在某一个场景中,这时你需要自己根据需求进行处理;
	Bundle Layout Preview:AB包布局预览

构建布局报告

1.构建布局报告说明:
        //构建布局报告提供了有关可寻址资源的构建打包的详细信息和统计信息
        //包括
        //1.AB包的描述
        //2.每个资源和AB包的大小
        //3.解析作为依赖项隐式包含在AB包中的不可寻址资源
        //4.AB包的依赖关系

        //我们可以通过查看报告文件获取这些信息
        
2.如何查看构建布局报告:
        //1.启用调试构建布局功能
        //Edit > Preferences > Addressables
        //启用Debug Build Layout

        //2.只要我们构建打包可寻址资源后
        //就可以在Library/com.unity.addressables/文件夹中找到buildlayout.txt文件
        
3.构建布局报告的内容:
        //内容中主要包含:
        //1.摘要信息(包括AB包数量、大小等等)
        //2.每组相关信息(哪些资源,几个包,包大小等等)
        //3.依赖相关信息

配置相关

1.配置文件分类:我们在导入Addressables包之后创建的那些就是配置文件,AddressableAssetsData文件夹下的内容都是本质为ScriptableObject的数据配置文件,他们会影响我们的打包方式等等相关内容;

  • AssetGroups(资源组):当我们创建一个组就会多一些相关数据配置文件
  • AssetGroupTemplates:资源组模板,主要是对资源组的一些默认设置,可以自己创建模板在Project窗口右键或者点击+号,Create(创建)——>Addressables(可寻址)——>Group Templates(组模板)——>Blank Group Template(空白组模板);
    • Packed Assets:默认的打包资源数据配置模板;
  • DataBuilders:数据生成器,这些内容决定了在不同模式下,资源打包和使用的方式;
    • BuildScriptFastMode:构建脚本快速模式 ;
    • BuildScriptPackedMode:构建脚本打包模式;
    • BuildScriptPackedPlayMode:构建脚本打包播放模式;
    • BuildScriptVirtualMode:构建脚本虚拟模式;
  • AddressableAssetSettings:可寻址资源设置,该配置文件可以设置一些可寻址资源的一些公共设置;
  • DefaultObject:默认对象;

AddressableAssetSetting配置(可寻址资源设置)

1.Profile-概述配置:
	Profile In Use:可以在这选择使用的是哪一套配置文件
	Manage Profiles:点击它会打开管理配置文件窗口
	
	
2.Diagnostics-诊断:
	Send Profiler Events:启用分析器事件,启用它后我们可以在Event Viewer窗口查看Addressable相关信息
	Log Runtime Exceptions:记录运行时加载相关的异常
	
	
3.Catalog-目录相关设置,将资源的地址映射到其物理位置:
	Player Version Override:重写用于制定远程目录名称的时间戳,如果不设置默认使用时间戳作为远程目录命名;
	Compress Local Catalog:在压缩的AssetBundle文件中生成目录。可以压缩大小,但是会增加生成和加载的时间
	Optimize Catalog Size:通过为内部ID创建查找表来减小目录的大小。会增加加载目录所需的时间
	
	
4.Content Update-内容更新:
	Disable Catalog Update on Startup:当可寻址系统在运行时初始化时,禁用自动检查更新的远程目录。您可以手动检查更新的目录。
	Content State Build Path:在何处生成由默认生成脚本生成的内容状态文件。
	Build Remote Catalog-构建远程目录(勾选后会出现新选项):
		Build & Load Paths:在何处生成和加载远程目录。从列表中选择一个配置文件路径,如果要分别设置生成路径和加载路径,请选择<custom>,仅在启用生成远程目录时可见;
		Build Path:远程构建路径,在何处构建远程目录。通常,应该使用RemoteBuildPath配置文件变量,仅当将生成和加载路径设置为<custom>时显示;
		Load Path:远程加载路径,用于访问远程目录的URL。通常,应该使用RemoteLoadPath配置文件变量,仅当将生成和加载路径设置为<custom>时显示;
		Path Preview:路径预览
		
		
5.(不重要)Custom Certificeate handle:用于自定义证书处理的类。该列表包含项目中扩展UnityEngine的所有类。网络。证书管理员。
	Max Concurrent Web Requests:系统对超过此限制的任何请求进行队列处理
	Catalog Download Timeout:等待目录文件下载的时间为多少秒。
	
	
6.Build-生成构建相关设置:
	Ignore Invalid/Unsupported Files in Build:忽略生成中无效不受支持的文件,如果启用,Addressable生成脚本将排除无效或不受支持的文件,而不是中止生成;
	Unique Bundle IDs:唯一约束ID,是否为每个构建中的包生成一个唯一的名称;
	Contiguous Bundles:连续捆绑,生成更高效的捆绑包布局。如果您有Addressables 1.12.1或更早版本生成的捆绑包,请禁用此选项以最小化捆绑包更改;
	Non-Recursive Dependency Calculation:非递归依赖计算,不使用递归计算依赖项;
	Shader Bundle Naming Prefix:着色器包命名前缀;
	MonoScript Bundle Naming Prefix:Mono脚本包命名前缀;
	Strip Unity Version From AssetBundles:从AssetBUndles中剥离Unity版本,决定是否从包头中删除版本信息;
	Disable Visible Sub Asset Representations:禁用可见子资源,如果您不直接使用子对象(Sprite、子网格等),则启用此选项可以提高构建时间;
	
	
7.Build and Play Mode Scripts-构建和编辑器模式脚本,在编辑器中进入播放模式时,选择Addressable系统如何加载资产,这些脚本处理默认的构建进程,并提供不同的方式在编辑模式下访问数据,我们可以在AddressableAssetData/DataBuilders文件夹中找到这些脚本,如果要为他们自定义脚本,那么对应的脚本需要时BuildScriptBase的子类,并且继承IDataBuilder:
	Use Asset Database:使用资源数据库
	Simulate Groups:模拟组
	Use Existing Build:使用现有版本
	Default Build Scripts:默认生成脚本
	
	
8.Asset Group Templates-资源组模板:
	Packed Asset:打包资源,定义可用于创建新组的模板列表,创建新模板时,必须先将其添加到此列表中,然后才能使用它,Addressables包包含一个模板,其中包含默认构建脚本使用的模式。您可以在AddressableAssetData/AssetGroupTemplates文件夹中找到该模板。
	
	
9.Initialization Objects-初始化对象列表:配置初始化对象,可以在Project右键Create>Addressables>Initialization(初始化)>Cache Initialization Setting(缓存初始化设置);
	Compress Bundles:是否压缩包
	Cache Directory Override:缓存目录覆盖
	[Obsolete]Expiration Delay:过期延迟(过时了)
	Limit Cache Size:限制缓存的大小
	Maximum Cache Size:最大缓存大小

Packed Assets打包资源配置

1.Content Packing & Loading:
	Build & Load Paths:配置文件路径对,定义可寻址构建系统在哪个路径为此组创建内容,以及可寻址系统在运行时在何处加载这些内容,只有定义为Custom时才会出现下面的选项;
	Build Path-打包路径:
		LocalBuildPath-本地路径
		RemoteBuildPath-远程路径
	Load Path-加载路径:
		LocalLoadPath-本地路径
		RemoteLoadPath-远程路径
	Path Preview:路径预览
	
	
	
2.Advanced Options-高级选项:
	(1*).Asset Bundle Compression:AB包的压缩方式,默认为LZ4,它通常是最有效的选项,建议使用;
		Uncompressed:不压缩,包较大,不推荐;
		LZ4:压缩,相对LZMA大一点点,建议使用,用什么解压什么,内存占用低;
		LZMA:压缩最小,解压慢,用一个资源要解压所有;
		
	(2*).Include In Build:包含在构建中,是否在内容生成中包含此组中的资源。如果取消勾选,那么在选择打包时,不会打包该组内容;
	
	(3)Force Unique Provider:强制唯一提供者,Addressable是否对此组使用资源提供程序类的唯一实例。如果您有此组中的资产类型的自定义提供程序实现,并且这些提供程序的实例不能在组之间共享,则启用此选项。
	
	(4*).Use Asset Bundle Cache:使用AB包缓存,是否缓存远程分发的包;
	
	(5*).Asset Bundle CRC-是否在加载前验证AB包的完整性:
		Disabled:永远不检查完整性
		Enabled,Including Cached:检查完整性,包括缓存也检查
		Enabled,Excluding Cached:检查完整性,但是不检查缓存的包
	(6).Use UnityWebRequest for Local Asset Bundle:加载AB包时,使用UnityWebRequestAssetBundle.GetAssetBundle而不是AssetBundle.LoadFromFileAsync;
	
	(7).Request Timeout:下载远程包时超时的间隔时间;
	
	(8).Use Http Chunked Transfer:下载包时是否使用HTTP/1.1块传输编码方法(在2019.3+中被废弃和忽略);
	
	(9).Http Redirect Limit:下载包时允许重定向的次数。无限制设置为-1;
	
	(10).Retry Count:重试失败下载的次数;
	
	(11).Include Addresses in Catalog:是否将地址字符串包括在目录中。如果不使用地址字符串在组中加载资产,则可以通过不包括它们来减小目录的大小;
	
	(12*).Include GUIDs in Catalog:是否在目录中包含GUID字符串。您必须包含guid字符串才能使用资产参考。如果不使用AssetReferences或GUID字符串在组中加载资产,则可以通过不包括它们来减小目录的大小;
	
	(13*).Include Labels in Catalog:是否在目录中包含标签字符串。如果不使用标签在组中加载资产,则可以通过不包括这些资产来缩小目录的大小;
	
	(14*).Internal Asset Naming Mode-如何在内部命名目录中的资源:
		Full Path:全路径
		FileName:文件名
		GUID:资源的Guid字符串
		Dynamic:Addressables根据组中的资源选择最小的内部名称
		
	(15).Internal Bundle Id Mode-确定如何构造资产绑定的内部ID。例如,当您设置群GUID选项,Addressables通过将组名与包guid字符串组合来创建包ID:
		Group Guid:组的Guid
		Group Guid Project Id Hash:组的ID和工程ID的哈希
		Group Guid Project Id Entries Hash:组的ID和工程ID项的哈希
		
	(16*).Cache Clear Behavior-确定安装的应用程序何时从缓存中清除AB包:
		Clear When Space Is Needed In Cache:在缓存中需要空间时清除;
		Clear When When new Version Loaded:加载新版本时清楚;
		
	(17*).Bundle Mode-打包模式,如何将此组中的资产打包到包中:
		Pack Together:创建包含所有资产的单个包;
		Pack Separately:为组中的每个主要资产创建一个包。如精灵图片中的精灵图片被包装在一起。添加到组中的文件夹中的资产也打包在一起;
		Pack Together by Label:为共享相同标签组合的资产创建一个包;
		
	(18).Bundle Naming Mode-如何构造AB包的文件名:
		Filename:文件名
		Append Hash to Filename:将哈希附加到文件名
		Use Hash of AssetBundle:使用AB包的哈希
		Use Hash of FileName:使用文件名的哈希
		
	(19*).Asset Load Mode-资源加载模式:
		Requested Asset And Dependencies:请求的资源和依赖项;
		All Packed Assets And Dependencies:所有包中的资源和依赖项;
		
	(20).Asset Provider-资源提供者,定义提供程序类Addressable用于从该组生成的AssetBundles加载资产。将此选项设置为Bundles供应商的资产除非您有一个自定义提供程序实现来从资产绑定中提供资产:
		Content Catalog Provider:内容目录提供器
		AssetBundle Provider:AB包提供器
		Assets from AssetDatabase Provider:资源来自资源数据库提供器
		Sprites from Atlases Provider:精灵来自图集提供器
		Assets from bundles provider:资源来自绑定提供器
		Json Asset Provider:Json资源提供器
		Assets from Legacy Resources:资源来自遗留的Resources提供器
		Text Data Provider:文本数据提供器
		Virtual AssetBundle Provider:虚拟AB包提供器
		Assets from Virtual Bundles:资源来自虚拟绑定
		
	(21).Asset Bundle Provider:AB包提供器,定义由该组生成的提供程序类Addressable用于加载AssetBundles。将此选项设置为资产束提供者除非您有一个自定义提供程序实现来提供资产绑定;



3.Content Update Restricion-内容更新限制:
	Can Change Post Release:可以改变发行后内容,该模式不移动任何资源,如果包中的任何资源发生了更改,则重新构建整个包;
	Cannot Change Post Release:无法改变发布后内容,如果包中任何资源已经改变,则[检查内容更新限制]工具会将其移动到为更新创建的新组中。在进行更新构建时,从这个新组创建的AssetBundles中的资产将覆盖现有包中的版本;



4.Add Schema(添加模式)-你可以将任意数量的架构模式分配给一个组,我们甚至可以通过继承AddressableAssetGroupSchema定义自己的架构模式;
	Content Packing Loading:内容打包加载相关;
	Content Update Restriction:内容更新限制;
	Resources and Built In Scenes:在内置数据中显示哪些类型的内置资源,可以选择是否显示 资源和内置场景;

资源打包(发布)

1.资源打包注意事项:

  • 场景资源始终有自己单独的包:当一个可寻址包中有场景资源和普通资源时,场景资源和其它资源始终会被分开打包;
  • 资源依赖的注意事项:类似于AssetBundle,如果资源a和资源b都使用了资源c,但是资源a和b是可寻址资源但不在一个组中,而c不是可寻址资源,那么这时资源c分别会被打进a和b的包,相当于这时的c就被重复利用了,浪费了空间,较好的解决方案是:将c也作为可寻址资源, a-A包 b-B包 c-C包, 这时c不会被打进A、B包,A、B包只会依赖于C,而Addressable会自动帮助我们处理依赖问题;
  • 合理安排可寻址资源分组:同类型,同作用放一起,比如角色组、怪物组、武器组、衣服组、登录UI组、装备UI组、音效组、可变贴图组、图集组等等;
  • 关于包的数量(分组的数量):要根据实际情况来对资源进行布局,包(分组)过多、包(分组)过大都不太好,要根据自己的实际情况进行组的安排;

2.本地资源发布:所有组的加载和发布都选择本地路劲,LocalBuildPath-打包路径,LocalLoadPath-加载路径(注意:使用默认设置,当发布应用程序时,会自动帮我们将AB包放入StreamingAssets文件夹中,如果修改了路径,我们需要自己将内容放入StreamingAssets文件夹中);

3.远程资源发布:在远端的电脑上搭建Http服务器,将打包出来的资源上传到对应服务器上即可,资源加载组时会自动判断是本地资源还是远端资源,无需向AssetBundle一样进行手动设置;

4.资源更新:当项目正式发布后,对于远程加载的资源,我们可以通过改变资源服务器上的AB包来更新游戏,和AssetBundle不同的是,Addressables会自动帮助我们判断哪些资源更新了,并加载最新的内容;

  • 整包更新:组设置为 Can Change Post Release,直接在Build中点击资源更新而不是发布,之后会让选择一个更新日志文件,覆盖即可,整包更新指,某一个分组的资源发生变化后,我们需要将其整体进行打包,这种方式适用于大范围资源更新时使用;
  • 局部更新:组设置为 Cannot Change Post Release,首先先在Tools工具下检查更新,然后再Build中更新资源,这步同上,当资源有变化时,我们可以单位发生变化的内容变成AB包,之后使用该资源,Addressables会自动加载最新的内容,它相对整包更新来说,更节约时间和流量;

补充知识

资源加载相关

根据资源定位信息加载资源

1.加载资源Addressables做的事情:

  • 1.查找指定键的资源位置;
  • 2.收集依赖项列表;
  • 3.下载所需的所有远程AB包;
  • 4.将AB包加载到内存中;
  • 5.设置Result资源对象的值;
  • 6.更新Status状态变量参数并且调用完成事件Completed(如果我们启用了 Log Runtime Exceptions选项 会在Console窗口打印信息);

2.资源定位信息API使用: Addressables.LoadResourceLocationsAsync(基本和资源加载一样),使用它可以获取一些额外信息,可以利用这些信息处理一些特殊需求,并且资源定位信息加载资源并不会加大我们的开销;

  • PrimaryKey:资源主键(资源名);
  • InternalId:资源内部ID(资源路径);
  • ResourceType:资源类型(Type可以获取资源类型名);

    异步加载的其他方式

1.协同程序:

IEnumerator LoadAsset()
{
    handle = Addressables.LoadAssetAsync<GameObject>("Cube");
    //一定是没有加载成功 再去 yield return
    if(!handle.IsDone)
        yield return handle;

    //加载成功 那么久可以使用了
    if (handle.Status == AsyncOperationStatus.Succeeded)
    {
        print("协同程序创建对象");
        Instantiate(handle.Result);
    }
    else
        Addressables.Release(handle);
}

2.异步函数(async和await )

async void Load()
{
    handle = Addressables.LoadAssetAsync<GameObject>("Cube");

    AsyncOperationHandle<GameObject> handle2 = Addressables.LoadAssetAsync<GameObject>("Sphere");

    //单任务等待
    //await handle.Task;

    //多任务等待
    await Task.WhenAll(handle.Task, handle2.Task);

    print("异步函数的形式加载的资源");
    Instantiate(handle.Result);
    Instantiate(handle2.Result);
}

关于AsyncOperationHandle

1.无类型句柄转换
	AsyncOperationHandle<Texture2D> handle = 			Addressables.LoadAssetAsync<Texture2D>("Cube");
	AsyncOperationHandle temp = handle;
	//把无类型句柄 转换为 有类型的泛型对象
	handle = temp.Convert<Texture2D>();

2.获取加载进度
        while (!handle.IsDone)
        {
            DownloadStatus info = handle.GetDownloadStatus();
            //进度
            print(info.Percent);
            //字节加载进度 代表 AB包 加载了多少
            //当前下载了多少内容 /  总体有多少内容 单位是字节数
            print(info.DownloadedBytes + "/" + info.TotalBytes);
            yield return 0;
        }

自定义更新目录和下载AB包

1.目录的作用
        //目录文件的本质是Json文件和一个Hash文件
        //其中记录的主要内容有
        //Json文件中记录的是:
        //1.加载AB包、图集、资源、场景、实例化对象所用的脚本(会通过反射去加载他们来使用)
        //2.AB包中所有资源类型对应的类(会通过反射去加载他们来使用)
        //3.AB包对应路径
        //4.资源的path名
        //等等
        //Hash文件中记录的是:
        //目录文件对应hash码(每一个文件都有一个唯一码,用来判断文件是否变化)
        //更新时本地的文件hash码会和远端目录的hash码进行对比
        //如果发现不一样就会更新目录文件

        //当我们使用远端发布内容时,在资源服务器也会有一个目录文件
        //Addressables会在运行时自动管理目录
        //如果远端目录发生变化了(他会通过hash文件里面存储的数据判断是否是新目录)
        //它会自动下载新版本并将其加载到内存中

2.手动更新目录
        //1.如果要手动更新目录 建议在设置中关闭自动更新

        //2.自动检查所有目录是否有更新,并更新目录API
        Addressables.UpdateCatalogs().Completed += (obj) =>
        {
            Addressables.Release(obj);
        };

        //3.获取目录列表,再更新目录
        //参数 bool 就是加载结束后 会不会自动释放异步加载的句柄
        Addressables.CheckForCatalogUpdates(true).Completed += (obj) =>
        {
            //如果列表里面的内容大于0 证明有可以更新的目录
            if(obj.Result.Count > 0)
            {
                //根据目录列表更新目录
                Addressables.UpdateCatalogs(obj.Result, true).Completed += (handle) =>
                {
                    //如果更新完毕 记得释放资源
                    //Addressables.Release(handle);
                    //Addressables.Release(obj);
                };
            }
        };

3.预加载包
        //建议通过协程来加载
        StartCoroutine(LoadAsset());
    //定义协程
    IEnumerator LoadAsset()
    {
        //1.首先获取下载包的大小
        //可以传资源名、标签名、或者两者的组合
        AsyncOperationHandle<long> handleSize = Addressables.GetDownloadSizeAsync(new List<string>() { "Cube", "Sphere", "SD" });
        yield return handleSize;
        //2.预加载
        if(handleSize.Result > 0)
        {
            //这样就可以异步加载 所有依赖的AB包相关内容了
            AsyncOperationHandle handle = Addressables.DownloadDependenciesAsync(new List<string>() { "Cube", "Sphere", "SD" }, Addressables.MergeMode.Union);
            while(!handle.IsDone)
            {
                //3.加载进度
                DownloadStatus info = handle.GetDownloadStatus();
                print(info.Percent);
                print(info.DownloadedBytes + "/" + info.TotalBytes);
                yield return 0;
            }

            Addressables.Release(handle);
        }
        
    }

引用计数规则

1.引用计数规则说明:Addressables内部会通过引用计数帮助我们管理内存,我们只需要保证 加载和卸载资源配对使用即可,以下分俩步来解释;

  • 计数说明:当我们通过加载使用可寻址资源时,Addressables会在内部帮助我们进行引用计数,使用资源时,引用计数+1,释放资源时,引用计数-1,当可寻址资源的引用为0时,就可以卸载它了,同时,AB包也有自己的引用计数(Addressables把它也视为可寻址资源),和资源计数类似但是分开计算;
  • 资源释放说明:为了避免内存泄露(不需要使用的内容残留在内存中),我们要保证加载资源和卸载资源是配对使用的,释放的资源不一定立即从内存中卸载,在卸载资源所属的AB包之前,不会释放资源使用的内存(比如自己所在的AB包 被别人使用时,这时AB包不会被卸载,所以自己还在内存中),我们可以使用Resources.UnloadUnusedAssets卸载资源(建议在切换场景时调用);

常见问题说明

1.用多包策略还是大包策略?
        //1.AB包太多(太小)的问题
        //  1-1:每个包都会有内存开销,如果加载过多的包可能会带来更多的内存消耗
        //  1-2:并发下载的问题,如果包小而多,以为着下载包时可能需要更多的时间
        //  1-3:目录文件会因为过多的包而变大,因为它要记录更多的包信息
        //  1-4:复用资源的可能性更大,比如多个包使用同样一个资源,但是该资源不是寻址资源,那么在每个包中都会有该资源

        //2.AB包太少(太大)的问题
        //  1-1:过大的包如果下载失败,下次会重新下载,因为使用UnityWebRequest下载包时不会恢复失败的下载
        //      比如100MB的包,下了50MB,玩家中断下载了,下次又得重新下
        //  1-2:能单独加载,但是不能单独卸载,更大的包意味着包中有更多资源,比如加载了1个大包中100个资源
        //      但是现在用完了99个,还剩一个再用,即使99都卸载了,但是由于引用计数这个大包也不会卸载
        //      就会造成内存的浪费

        //所以没有最好的策略,只有根据自己的项目需求合理安排分组打包
        //要根据资源的使用情况来合理设置资源分组,在分组时权衡好各方面的问题

2.哪种压缩方式更好?
        //AB包的压缩方式:不压缩、LZ4、LZMA
        //一般情况LZ4用于本地资源,LZMA用于远端资源
        //主要原因是LZMA的压缩内容更小,更节约下载时间和流量
        //注意:压缩不会影响加载内存的大小,只会影响包体大小,下载时间等

        //但是也要根据实际情况
        //比如:
        //1.不压缩:包体并不大的单机游戏,使用不压缩最好,没有包体大小的压力,加载也是最快的,因为不用解压
        //2.LZ4:它是基于块的压缩,所以提供了加载文件的能力,加载资源时不用全加载AB包,只加载使用的内容,相对LZMA来说更节约内存
        //3.LZMA:不建议用它在本地内容中,因为它虽然包最小,但是加载最慢,用它只是为了节约下载时间和极限压缩包体大小

        //综合来说,也没有最优的方式,还是要根据实际情况来选择
        //个人认为LZ4压缩方式,是相对比较优秀的一种方式

3.减小目录文件大小
        //当我们想要极限压缩包体大小时,可能希望优化目录文件的大小
        //1.压缩本地目录
        //  AddressableAssetSettings > Catalog > Compress Local Catalog
        //2.禁用内置场景和资源(Built In Data禁用)
        //  默认Addressables提供了从Resources等内置资源文件夹中加载资源以及加载内置场景
        //  如果你不通过Addressables加载他们,可以禁用,这样目录文件就不会包含其中信息
        //  但是我们就只能使用老方法加载同名
        //  个人建议取消,因为一般我们不会通过Addressables去加载非寻址资源

4.其他事项
        //1.关于AB包最大的限制,老版本不支持大于4G的包,虽然新版本中已经没有这个限制
        //但是为了兼容性,还是建议大小控制在4G以下

        //2.活用可寻址资源上的Groups View中的两个功能
        //Show Sprite and Subobject Addresses:当窗口中内容特别多时,禁用它可以提升窗口加载的性能
        //Group Hierarchy with Dashes:启用带破折号的层级结构
        //                             可以让我们在内容特别多时以层级结构查看分组信息