UFL10-1——TimerItem 具体实现
UFL10-1——TimerItem 具体实现
TimerItem 具体实现
由于计时器对象类是由计时器模块管理器管理,而且常常创建和销毁,因此该类对象可以由缓存池管理
123456789using UnityEngine.Events;/// <summary>/// 计时器对象,里面存储了计时器的相关数据/// </summary>public class TimerItem : IPoolObject{ public void ResetInfo() { }}
需要声明的关键成员
唯一ID
延时执行回调委托
间隔执行回到委托
总时间(毫秒)
间隔时间(毫秒)
是否开启
等等
123456789101112131415161718192021222324252627282930313233/// <summary>/// 唯一ID/// </summary>public int keyID;/// <summary>/// 计时结束后的委托回调/// </summ ...
UFL10——计时器模块
UFL10——计时器模块
Unity自带的计时功能
继承MonoBehaviour的组件,可以利用
Invoke 延迟执行逻辑
InvokeRepeating 间隔一定时间执行逻辑
协同程序 来计时
Update 中 自己实现计时功能
为什么要自己制作计时器模块
主要原因:
使用Unity自带的计时功能,不能为所有类服务(只能继承了 MonoBehaviour 才能使用)
利用协同程序和 Update 制作计时功能,如果需要都写,会产生代码冗余(写一堆类似重复的代码)
因此:我们将计时功能统一的进行管理,让所有系统都能够通过计时器模块进行计时
计时器模块的基本原理
想要达到的效果:
能够延时响应逻辑(比如:10s后执行某一逻辑)
在延时过程中,可以固定时间间隔响应逻辑(比如:10s后执行某一逻辑,但是10s内每隔1s又能响应其它逻辑)
基本原理:
定义一个计时器对象,计时器对象记录延时执行时间、间隔执行时间、执行结束回调委托、间隔执行回调委托等等
计时器模块中统一管理所有计时器对象,每个计时器对象有一个唯一ID,用来区分获取计时器对象
在计时器模块中利用 ...
UFL3-4——缓存池增加缓存对象种类
UFL3-4——缓存池增加缓存对象种类
缓存池模块(数据结构类、逻辑类)优化 主要目的
我们目前实现的缓存池,主要是针对场景上的GameObject对象的,我们只能对场景上的对象进行缓存池功能处理
但是在游戏开发中,还会存在大量的不需要挂载到场景上的实例化对象
比如一些数据结构类、逻辑类,它们并不依附于场景上的对象,而仅仅是被引用
举例:
一个自定义数据结构类,TestData t = new TestData();
当我们不使用它时,往往会将其置空,t = null;
下次又要使用时,再new,t = new TestData();
那么对于一些频繁使用的数据结构类或逻辑类,这样做也会产生大量的垃圾
因此我们完全可以修改缓存池模块,让其也支持对不挂载的类对象也进行复用
说人话:
缓存池模块(数据结构类、逻辑类)优化 主要目的是让缓存池支持回收复用不继承MonoBehaviour(不挂载GameObject)的类对象
缓存池模块(数据结构类、逻辑类)优化 制作思路
关键点:
池子容器父类里式替换父类装子类
1234/// <summary>/// 各个泛 ...
UFL9-3——输入控制模块的获取输入消息
UFL9-3——输入控制模块的获取输入消息
遗留问题:在真正制作改键功能时,我们应该如何获取到任意键盘或任意鼠标输入来记录对应的输入信息
实现获取输入信息逻辑
在InputManager的更新函数中,获取当前输入内容,用委托返回给外部
主要思路:
当存在某个键按下输入时,遍历监听KeyCode枚举中所有键位,检测是哪个键位输入了
当没有监听到时,监听鼠标左中右键键位,检测是哪个键位输入了
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051//是否开启了输入检测private bool isCheckInput;//用于在改键时获取输入信息的委托,只有当Update内获取到信息的时候 再通过委托传递出去private UnityAction<InputInfo> getInputInfoCallBack;private InputManager(){ MonoManager.Instance.AddUpdateLis ...
UFL9-2——输入控制模块的改键功能
UFL9-2——输入控制模块的改键功能
分析改键功能需求
改键功能应该是针对某一个行为的
游戏中的行为是固定的,我们需要改变的是触发该行为的按键
比如:角色有技能1、技能2、技能3,我们改变的是触发这些行为的输入
具体键位的触发不应该写死,而是需要根据存储的键位数据进行初始化或进行修改
键位的修改可以是键盘输入,也可以是鼠标输入,输入类型也可以是任意的
比如:触发技能1,可以修改为键盘输入,也可以修改为鼠标输入
可以是按下、可以是抬起、也可以是长按,具体是哪种应该根据你的需求变化
根据需求整理思路并制作
输入管理器主要做的事情,根据输入的信息,触发对应的事件,其中输入信息可变,触发的事件也可变
改键功能应该是针对某一个行为的,触发的事件类型应该是针对行为的,因为行为一般在游戏中是固定的
因此,我们在事件中心触发的事件不应该再是某种操作类型,而是某种行为,
因此我们可以把原来的操作类型事件如:E_Mouse 等删除或者注释,转而声明各种行为的事件名
(热键事件诸如水平轴和垂直轴不能删除,因为它们的修改不是在管理器内实现的)
假设我们有三种事件需要去监听设备输入
1234567 ...
UFL9-1——输入控制模块的具体实现
UFL9-1——输入控制模块的具体实现
输入控制模块的基本原理(以键盘为例)
制作 InputManager 单例模式管理器
1234public class InputManager : BaseManager<InputManager>{ private InputManager() { }}
在输入管理器中进行按键检测
要检测哪个按键,就在帧更新方法内监听对应的方法,帧更新方法需要在添加到公共Mono模块的帧更新内
123456789101112131415161718private InputManager(){ MonoManager.Instance.AddUpdateListener(InputUpdate);}// 开启或者关闭输入模块管理的检测public void StartOrCloseInputManager(bool isCheckInput){ this.isCheckInput = isCheckInput;}private void ...
UFL9——输入控制模块
UFL9——输入控制模块
前置知识点
Unity中 Input 公共类 相关知识点(Unity四部曲之Unity入门中)
事件中心模块
注意:
本节课主要针对的是PC端,鼠标键盘输入相关的内容,如果是手游,会有些不同,但是整体思路是一致的
本节课中主要针对老输入系统(Input公共类)进行封装
新输入系统(InputSystem)相关知识详见:Unity进阶之InputSystem
为什么要制作 输入控制模块
制作输入控制模块主要是 降低 输入相关代码的耦合性,
以前我们制作老输入系统相关功能,都是在 Update 当中进行按键检测 处理对应逻辑
但是当游戏开发中存在角色切换功能时,可能就会存在冗余代码,
所以我们将通过输入控制模块来降低代码耦合性,减少冗余代码
输入控制模块的具体实现
输入控制模块的具体实现
输入控制模块的改键功能
输入控制模块的获取输入消息
UFL8——场景切换模块
UFL8——场景切换模块
前置知识点
场景切换 相关知识点 (Unity四部曲之Unity入门)
协同程序 相关知识点 (Unity四部曲之Unity基础)
委托 相关知识点(C#四部曲之C#进阶)
为什么要制作场景切换模块
在游戏开发中很多时候可能需要进行场景切换,只要存在场景切换,我们往往需要在 切换场景时 和 切换场景结束后 进行一些操作
比如:
切换场景中
更新Loading界面进度条
切换场景后
隐藏Loading界面,动态创建场景中关卡信息:如角色、怪物、场景物件等等
因此为了避免有太多关于切换场景的冗余代码,并且为了使用更方便
我们可以将切换场景的逻辑统一整理在一个场景切换管理器中
实现场景切换模块的主要思路
制作 SceneMgr 单例模式管理器
1234public class SceneMgr : BaseManager<SceneMgr>{ private SceneMgr() { }}
实现同步加载场景 的公共方法
12345678//同步切换场景的方法public void L ...
UFL7——UI管理器的自定义事件添加函数
UFL7——UI管理器的自定义事件添加函数
前置知识点:UGUI中 EventTrigger 相关知识点(UI四部曲之UGUI 中)
为什么要进行 自定义事件添加函数 优化
我们在制作UI功能时,经常会有这样的需求:
为一些不带默认事件的控件添加自定义事件,比如 Image、Text 这些基础组件,想为他们添加点击、单击、拖拽等事件监听
为一些带默认事件的控件添加自定义事件,比如为 Button 按钮添加鼠标进入、鼠标移除等事件监听
等等
1234567891011121314151617EventTrigger eventtrigger = GetControl<Button>("btnStart").gameObject.AddComponent<EventTrigger>();//鼠标抬起EventTrigger.Entry entry = new EventTrigger.Entry();entry.eventID = EventTriggerType.PointerUp;entry.callback.AddListe ...
UFL8——UI管理器的隐藏面板可选销毁优化
UFL8——UI管理器的隐藏面板可选销毁优化
为什么要进行 隐藏面板可选销毁 优化
我们目前隐藏面板时,会直接将面板销毁,下次创建时再重新创建
优点:当存在内存压力时,直接销毁面板后,当内存不足时会触发GC,不会因为存在没有使用的面板引用而造成内存崩溃
缺点:会产生内存垃圾加快GC的触发,频繁的销毁创建会增加性能消耗
也就是说我们不能直接将面板隐藏改成不销毁,而应该改为可以让我们自己控制最好
我们可以根据项目的实际情况 选择性的使用失活或销毁
隐藏面板可选销毁实现
主要制作思路
无需使用缓存池,因为缓存池主要是提供给非唯一对象使用的,UI面板大部分情况下是唯一的,因此我们直接在UI管理器中修改逻辑即可
主要实现内容
隐藏面板时,可以选择销毁还是失活
显示面板时,如果存在直接激活,如果不存在再重新创建
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 ...