UFL7-3——UI管理器的异步加载优化
UFL7-3——UI管理器的异步加载优化
为什么要进行异步加载优化
我们之前制作UI管理器时,加载资源时是在测试模式下,始终使用的是编辑器同步加载模式
若真正使用异步加载时,可能会存在报错风险
举例重现问题:
构建AB包
采用异步加载方式加载AB包中的UI面板资源
将ABResManager的isDebug设置为false,使得加载会选择AB包加载
123456789101112131415161718192021222324252627282930using UnityEngine;using UnityEngine.Events;/// <summary>/// 用于进行加载AB相关资源的整合,在开发中可以通过EditorResManager去加载对应资源去进行测试/// </summary>public class ABResManager : BaseManager<ABResManager>{ private bool isDebug = false; private ABResManager() ...
UFL7-2——UI管理器
UFL7-2——UI管理器
制作UI管理器的目的
方便管理所有UI面板,控制UI面板的显示隐藏,提供公共API供外部使用,比如:
显示面板
隐藏面板
获取面板
添加自定义事件
等等
UI管理器层级规划
主要思路:
UI面板在任何场景都会显示,因此Canvas和EventSystem对象应该过场景不移除,并且保证唯一性和动态创建
UI管理器 为 不继承MonoBehaviour的单例模式
1234public class UIManager : BaseManager<UIManager>{ private UIManager() { }}
在构造函数中动态创建设置好的 Canvas 和 EventSystem 预设体(如果使用了UI摄像机,也需要单独处理摄像机预设体)
先在场景上创建 Canvas 和 EventSystem 以及 UI摄像机 预设体
然后,在UI管理器的构造函数内动态创建这三个预设体(方便在切换场景的情况下使用)
123456789101112131415161718192 ...
UFL7-1——UI面板基类
UFL7-1——UI面板基类
前置知识点
里氏替换原则
Dictionary 相关知识点(C#四部曲之C#进阶中)
委托 闭包 相关知识点(C#四部曲之C#进阶中)
GetComponentsInChildren(Unity四部曲之Unity入门中)
实现UI面板基类
主要实现思路:
在基类中完成声明组件、查找组件、监听组件相关功能
让子类可以直接处理事件逻辑,获取指定控件
主要实现内容:
通用的查找组件功能
我们可以使用GetComponentsInChildren方法,来查找面板下所有的UI控件,将其添加到Dictionary<string, UIBehaviour>字典内统一管理
注意,往往面板上会存在一般不会使用的同名的默认名控件,如Text (TMP),Image等等
因此我们声明一个列表,记录各个控件的默认名,当获取到控件和默认名一致时,就跳过该控件
还有一种情况是,一个UI对象上挂载了多个不同的控件脚本,对于这种情况,我们可以调整控件查找的先后顺序,越重要的越先找
重要的控件就会先被记录,而后面即使找到了同一UI对象上的另外一个控件 ...
UFL7——UI管理模块
UFL7——UI管理模块
前置知识点
UGUI 相关知识点(UI四部曲之UGUI中)
Dictionary 相关知识点(C#四部曲之C#进阶中)
委托 相关知识点(C#四部曲之C#进阶中)
MonoBehaviour 相关知识点(Unity四部曲之Unity入门中)
回顾制作UI面板的传统流程
拼面板(必须做)
声明组件(重复工作)
查找组件(重复工作)
监听事件(重复工作)
处理逻辑(必须做)
UI管理模块的基本原理
制作UI面板基类,帮助我们自动化的查找组件,监听事件,无需每次写大量冗余代码
将2、3、4步做成自动化的,无需重复去做,解决方案一般有两种:
自动化工具生成代码(使用Unity编辑器拓展相关知识完成)
基类中规范冗余代码(本课程讲解的)
制作UI管理器,管理所有UI面板,UI面板的显示隐藏都通过UI管理器来进行管理,提供公共API供外部使用
比如:
显示面板
隐藏面板
获取面板
添加自定义事件
等等
按照这个思路制作UI管理模块后,我们之后在制作UI功能时,只需要把重点放在拼面板,和面板逻辑处理上了
具体实现
UI面板基类
UI ...
UFL6-3——音效管理模块优化
UFL6-3——音效管理模块优化
优化频繁创建删除音效组件
目前我们音效管理器中的音效组件会频繁的创建和删除
这样会产生大量的内存垃圾,并且频繁创建对象也会带来性能消耗
因此我们可以利用缓存池对其进行优化
按照之前实现的缓存池要求,在场景上创建一个挂载音效源的对象,然后挂载一个poolObj脚本,然后设置最大存在数量maxNum
因此,我们不再需要一个专门挂载音效源的对象,而是转为使用缓存池创建挂载音效源的对象
播放音效时,从缓存池内取出音效对象,停止播放音效(因为该音效可能正在播放其他音效),设置音效切片
停止播放或者帧更新检测播放停止时,清空关联的音效切片,从管理列表内移除,将音效对象压回对象池内,
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758//管理正在播放的音效private List<AudioSource> soundList = new List<AudioSource> ...
UFL6-2——音效管理模块音效部分实现
UFL6-2——音效管理模块音效部分实现
实现音效管理模块 音效 相关内容
主要实现内容
注意:
音效和背景音乐不同
音效存在多个,并且音效需要管理是否结束,因此需要用容器记录音效组件
音效分为循环和非循环
非循环的需要我们检测它播放结束,循环的需要让外部进行管理
播放音效
如果不考虑3D音效的话,可以将所有的音效源组件添加到一个单独的对象上,方便管理
每次播放音效时,都需要将播放音效的音效源组件添加到列表内,方便管理,同时还需要一个回调函数参数,将音效源组件传递出去
12345678910111213141516171819202122232425262728//用于音效组件依附的对象private GameObject soundObj = null;//管理正在播放的音效private List<AudioSource> soundList = new List<AudioSource>();//音效音量大小private float soundVolume = 0.1f;// 播放音效public void PlaySound(string ...
UFL6-1——音效管理模块音乐部分实现
UFL6-1——音效管理模块音乐部分实现
实现音效管理模块 音乐 相关内容
声明MusicManager,继承 不继承MonoBehaviour的单例模式基类
1234567/// <summary>/// 音乐音效管理器/// </summary>public class MusicManager : BaseManager<MusicManager>{ private MusicManager() { }}
播放背景音乐
在场景上添加一个唯一的不可销毁的对象,该对象挂载一个播放背景音乐的音效源,
音效管理模块需要关联这个音效源,通过这个音效源来控制背景音乐的播放
12345678910111213141516171819202122//背景音乐播放组件private AudioSource bgmSource = null;public void PlayBGM(string name){ //动态创建播放背景音乐的组件,并且不会因为过场景而移除 //保证背景音乐在 ...
UFL6——音效管理模块
UFL6——音效管理模块
前置知识点
Unity音频 相关知识点 (Unity四部曲之Unity入门中)
List 相关知识点(C#四部曲之C#进阶中)
音效管理模块
主要作用
游戏开发中有很多会用到音乐的地方
比如:背景音乐、打击音效、UI音效、特效音效、等等
而不同的音乐音效会在不同的模块中去进行播放
比如:技能释放、怪物受伤、角色受伤、副本通关、奖励发放
如果我们不写一个音效管理模块,那么在播放音乐音效时会有很多冗余的代码,不方便管理,整体结构会显得较为杂乱,
因此我们单独实现一个独立的音效管理模块,专门用于管理控制游戏中的所有音乐相关的功能
基本原理
实现一个音乐管理器,提供一些公共方法给外部使用,比如:
播放背景音乐
停止背景音乐
播放音效
停止播放音效
设置背景音乐大小
设置音效大小
等等
具体实现
音效管理模块音乐部分实现
音效管理模块音效部分实现
音效管理模块优化
UFL5-8——UnityWebRequest资源加载模块
UFL5-8——UnityWebRequest资源加载模块
前置知识点:
UnityWebRequest 相关知识 —— Unity网络开发基础
泛型 相关知识 —— C#四部曲C#进阶中
协同程序 相关知识 —— Unity四部曲之Unity基础中
反射中的Type 相关知识 —— C#四部曲C#进阶中
委托 相关知识 —— C#四部曲C#进阶中
重要内容回顾
WWW 和 UnityWebRequest 都是Unity提供给我们的简单的访问网页的类,我们可以利用它们来进行数据的上传和下载
除此之外,它们都支持 file:// 本地文件传输协议,我们可以利用该协议来异步加载本地文件
特别是在Android平台时,我们无法直接通过C#中的File公共类加载StreamingAssets文件夹中的内容
我们需要使用 WWW 或 UnityWebRequest 类来加载
UnityWebRequest资源加载模块我们主要做什么
我们主要封装 UnityWebRequest 当中的
获取文本或二进制数据 方法
获取纹理数据 方法
获取AB包数据 方法
制作UWQ ...
UFL5-7——AB包资源管理器的同步加载修改
UFL5-7——AB包资源管理器的同步加载修改
修改同步加载主要面对的问题
在进行同步加载时如果遇到有AB包正在被异步加载应该如何解决?
通过我们之前学习的 潜在问题考虑 得知,在进行异步加载时再重复加载相同AB包是会报错的
即使是同步加载,我们也必须等待异步加载结束,再进行下一步
修改ABMgr中的同步加载相关逻辑
注释之前的同步加载代码
12345678//同步加载,不指定类型//public Object LoadRes(string abName, string resName);//同步加载,使用type指定类型//public Object LoadRes(string abName, string resName, System.Type type);//同步加载,使用泛型指定类型//public T LoadRes<T>(string abName, string resName) where T : Object;
在异步加载的基础上进行修改
添加一个isSync参数,该参数为true时,当遇到未加载的AB包或者资源,会全部所有同步API加载 ...