UFL5-6——AB包资源管理器的异步加载修改
UFL5-6——AB包资源管理器的异步加载修改
管理器代码继承自:UH1L4——AB包资源管理器
重新按照ABMgr中的规则进行AB包打包
ABMgr异步加载修改主要目标
将ABMgr中的异步加载方法彻底异步化,让其中的依赖包加载、资源包加载、资源加载都变为异步加载
注意:主包可以保留同步加载
需要考虑的主要问题
某个AB包当正在异步加载时又进行重复加载,遇到这种情况时,我们需要避免重复加载报错
因此我们不应再次加载,而是等待之前的异步加载结束后直接使用
首先将同步加载AB包的方法LoadAB进行拆分,将加载主包的逻辑提取出来,新声明一个LoadMainAB去实现
12345678910111213141516171819202122232425262728293031323334private void LoadMainAB(){ //加载主包 if (mainAB == null) { mainAB = AssetBundle.LoadFromFile(PathUrl + MainABName); ...
UFL5-5——AB包资源管理器回顾及潜在问题考虑
UFL5-5——AB包资源管理器回顾及潜在问题考虑
前置知识点:UH1——AssetBundle
Assetbundle资源加载模块我们主要做什么
目前已有的AB包资源管理器:UH1L4——AB包资源管理器
目前已有的ABManager中的异步加载部分,只是从AB包中异步加载资源,并没有真正的去异步加载AB包本身,
我们要做的事情,就是对ABManager进行优化,让其中的异步加载真正意义上的实现异步,就是将AB包本身的加载也变为异步的
异步加载AB包可能带来的问题
如果我们想要将ABManager中的异步加载方法改为真正意义上的异步
所谓真正意义上的异步是指:不仅从AB包中加载资源是异步的,还需要在加载AB包时也采用异步
那么我们就需要考虑一个问题,如果当我们正在异步加载AB包时,又进行了一次同步加载AB包是否会报错(因为AB包不允许重复加载)
举例说明问题
假设要加载Assets/StreamingAssets/PC下的testAB包
如果先异步加载再同步加载AB包,则同步加载语句将会报错,因为AB包不可重复加载
123456789101112131415pub ...
UFL5-4——Editor资源加载模块
UFL5-4——Editor资源加载模块
Editor资源加载模块
Editor资源加载的主要作用
当项目主要采用AssetBundle资源加载时,用于在开发时进行资源加载,方便资源管理,避免资源重复打包
Editor资源加载的基本原理
利用Unity编辑器拓展中的相关API来进行加载即可
AssetDatabase.LoadAssetAtPath()
EditorGUIUtility.Load()
Editor资源加载的主要作用
避免在开发时频繁的打AB包降低开发效率
方便资源管理,避免资源重复打包
在进行项目开发时,最终发布的项目一般为了达到以下两个目的
减小包体大小
热更新
最终会通过AssetBundle资源加载作为主要加载方式
那么也就是说最终我们发布项目时,几乎所有的的游戏资源都会在AB包中的
AB包最终会放置在 StreamingAssets 中 或者 远程资源服务器 中
但是在开发期间,如果进行频繁的资源打包(资源放入AssetBundle包),会大大降低我们的开发效率。
因此我们在开发功能时,可以不通过AB包加载资源,而是在最终要测试或 ...
UFL5-3——添加引用计数的Resource资源加载模块
UFL5-3——添加引用计数的Resource资源加载模块
通过引用计数判断资源是否使用的问题
在卸载资源时,我们并不知道是否还有地方使用着该资源
UnloadUnusedAssets是卸载没有使用的资源,我们无法判断是否使用
我们可以使用引用计数来解决上述问题
引用计数是一种内存管理技术,用于跟踪资源被引用的次数
我们通过一个整形int变量来记录资源的使用次数
当有对象引用该资源时,计数器会增加;当对象不再引用该资源时,计数器会减少
向ResManager中加入引用计数功能
为ResInfo类加入引用计数成员变量和方法
1234567891011121314151617181920public class ResInfo<T> : ResInfoBase{ public T asset; //资源 public UnityAction<T> callBack; //用于异步资源加载完后 传递资源到外部的委托 public Coroutine coroutine; ...
UFL5-2——优化Resources资源加载模块的异步加载
UFL5-2——优化Resources资源加载模块的异步加载
异步加载问题指的是什么
每次进行异步加载时,都会开启一个协同程序,虽然Resources资源会在内部进行缓存,加载已加载过的资源,性能消耗不会太大
但是每次开启协程的过程也会浪费性能,因此我们希望对上节课的ResManager进行优化
不依赖Resources内部的缓存机制,而是自己来管理已经加载过的资源,从而解决异步加载时协同程序的频繁开启造成的性能浪费
例如下面的代码就是加载的一模一样的资源
123456789ResManager.Instance.LoadAsync<GameObject>("Test", (obj) =>{ Instantiate(obj);});ResManager.Instance.LoadAsync("Test", typeof(GameObject), (obj) =>{ Instantiate(obj as GameObject);});
我们想要达到的目的是:通过一个字 ...
UFL5-1——Resource资源加载模块的具体实现
UFL5-1——Resource资源加载模块的具体实现
前置知识点
C#中Dictionary相关知识点(C#四部曲之C#进阶中)
C#中委托事件相关知识点(C#四部曲之C#进阶中)
Unity中Resources相关知识点(Unity四部曲之Unity基础中)
Unity中协同程序相关知识点(Unity四部曲之Unity基础中)
Resources资源加载模块的具体实现
创建 ResourcesManager 继承 不继承MonoBehaviour的单例模式基类
12345678910using UnityEngine;using UnityEngine.Events;/// <summary>/// Resources 资源加载模块管理器/// </summary>public class ResManager : BaseManager<ResManager>{ private ResManager() { }}
为它封装Resources异步加载资源的相关方法(主要目的 避 ...
UFL5——资源加载模块
UFL5——资源加载模块
前置知识点
C#中Dictionary相关知识点(C#四部曲之C#进阶中)
C#中委托事件相关知识点(C#四部曲之C#进阶中)
C#中泛型相关知识点(C#四部曲之C#进阶中)
Unity中特殊文件夹相关知识点(Unity四部曲之Unity基础中)
Unity中协同程序相关知识点(Unity四部曲之Unity基础中)
Unity中UnityWebRequest相关知识点(Unity网络开发基础中)
Unity中AB包相关知识点(Unity热更新解决方案之Lua)
Unity中AssetDatabase相关知识点(Unity编辑器拓展中)
资源加载模块
资源加载模块的主要作用
方便统一管理各种资源加载卸载方式(Resources、AB包、UnityWebRequest、Editor)
方便异步加载资源(Resources、AB包、UnityWebRequest)
资源加载模块的基本原理
将各资源加载模式模块化 方便我们在加载资源时根据自己的需求进行选择性使用
抛出问题
我们目前有相当多的资源加载方案来加载不同文件夹下的资源,而不 ...
UFL4-4——事件中心的事件名优化
UFL4-4——事件中心的事件名优化
事件中心中 事件名优化 指的是什么
目前我们通过 字符串 作为事件名来区分各事件
明显的缺点:若触发或监听时,事件名 字符串 拼写错误会导致无法正确监听或触发事件
制作思路和具体实现
将事件名使用枚举进行统一管理,例如:
1234567891011121314/// <summary>/// 事件类型枚举/// </summary>public enum E_EventType{ /// <summary> /// 怪物死亡事件 —— 参数:Monster /// </summary> E_Monster_Dead, /// <summary> /// 玩家获取奖励 —— 参数:int /// </summary> E_Player_GetReward,}
然后,将EventCenter内所有使用到字符串事件名都改为使用枚举E_EventType的
12345678910111213141516171819 ...
UFL4-3——事件中心传递自定义参数
UFL4-3——事件中心传递自定义参数
事件中心中 参数类型自定义 指的是什么
上节课我们通过万物之父 object 利用里式替换原则(父类装子类),实现了在事件中心中传递参数
但是使用 object 时,当传递值类型参数时,存在装箱拆箱的性能浪费
而这节课要讲解的 参数类型自定义 指的就是 在传递数据时,
参数类型可以根据需求自己定义,想传什么就传什么,而不是固定的 object 类型
制作思路和具体实现
制作思路:
想让传递的参数类型可变,并且想传什么就传什么,我们可以很自然的联想到使用泛型UnityAction<T> 来制作该功能
但是我们需要解决以下关键问题:字典容器中的 泛型委托 如何提前定好类型
我们不能直接让泛型类型的委托UnityAction<T>作为Dictionary<TKey, TValue>的值,因为不同泛型参数的委托不是一种类型的
而且我们也不能通过直接让EventCenter变成泛型类的方法来解决这个问题,这样会破坏单例模式的唯一性
解决方案:里式替换原则(父类装子类)
声明一个EventInfo< ...
UFL4-2——事件中心传递参数
UFL4-2——事件中心传递参数
事件中心中传递参数指的是什么
希望在触发事件时传递数据,比如
怪物死亡时,将怪物信息传递出去
获取奖励时,将奖励信息传递出去
等等
传递数据的主要目的是,我们可以在各系统、模块、对象中获取到我们希望获取的有用信息
制作思路和具体实现
我们目前触发事件,是通过执行委托中存储的函数来执行各系统对应的逻辑,那么需要传递参数,我们很自然的联想到应该从委托入手
但是参数的类型可能有多种多样,我们可以采用万物之父 object 利用里式替换原则,父类容器装载子类对象的方式来传递参数
因此,将存储事件的委托字典eventDic的值从UnityAction转为使用UnityAction<object>,
其他相关方法AddEventListener和RemoveEventListener也修改为使用UnityAction<object>参数,
而触发事件的方法EventTrigger就需要额外传入一个object参数,在执行委托时将参数传进去
1234567891011121314151617181920212223242 ...