Unity MOBA 多人竞技手游制作教程
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.4 匹配逻辑实现

3.4.1 Time类基础知识

在游戏中经常会遇到有关计时的问题,比如记录匹配的时间等。在遇到这样的需求时,就会涉及Unity中Time类的使用。因此,在正式开始匹配逻辑前,先介绍相关知识点。

□ Time.time:从游戏开始到现在的时间,游戏的暂停时停止计算。

□ Time.timeSinceLevelLoad:表示从进入当前Scene到现在的时间,会因游戏暂停操作而停止计算。

□ Time.deltaTime:表示从上一帧到当前帧时间,以秒为单位。计时器通常用它进行计时。

□ Time.timeScale:时间缩放,默认值为1。值小于1,表示时间减慢;值大于1,表示时间加快。用于加速和减速游戏。

下面利用Time类的知识做一个简单计时器。

Step 01 创建一个Test场景,并在场景中创建一个Label用来显示时间。

Step 02 新建一个TimeTest脚本,并将此脚本挂载到Label对象上。

Step 03 打开脚本,定义公有变量TimeText表示场景中的Label,并在场景中给TimeText赋值。

Step 04 利用Time.deltatime记录时间,但是Time.deltatime得到的时间为float小数类型,而通常在游戏中计时用到的是整数类型,并且会将时间转换成某种格式。因此,需要将时间转换为固定格式。例如00:00:00(时:分:秒)。

Step 05 在Update函数中,Time.deltatime累加得到的时间就是记录的时间,赋值给seconds。当时间大于1分钟时,分钟minutes加1,并将秒数seconds清零,当分钟数minutes大于60时,小时数hours加1。时分秒数据获得后,利用time文本将数据以00:00:00的格式显示出来。代码如下所示。

Step 06 文本显示利用的是UILabel中的Text属性。所以直接获取text并将其赋值。

3.4.2 完善匹配逻辑

◎组队

UI界面搭建中,组队界面已经完成,只是默认在隐藏状态。本游戏教程是一对一的网络游戏,所以本节忽略了进入游戏大厅的部分内容,直接开始组队匹配。客户端在连接服务器后,通过发送请求消息与服务器进行交互。先发送登录请求,服务器端验证完成后,会返回玩家信息等。所有发送消息通过NetWorkManager的SendMsg函数来完成,详细的原理不在这里赘述,有兴趣的读者可以参考框架部分内容。

发送消息时,消息的类型包含在通信协议中。如申请匹配的消息为AskStartMatch,此消息发送给服务器端,服务器端执行相应的处理后应答给客户端,客户端进行后续的动作。协议部分先不过多叙述,等用到的时候再进行说明。

组队的详细流程如下。

Step 01 客户端发送请求匹配消息(发送GCToCS.AskCreateMatchTeam消息),调用OnMatch函数,代码如下所示:

Step 02 服务器处理后会返回开始组队匹配的消息(GSToGC.MsgID.eMsgToGCFromGS_NotifyMatchTeamBaseInfo)。

Step 03 MessageHandler注册上一步的消息处理,收到后对消息进行解码,接着广播GameEventEnum.UserEvent_NotifyMatchTeamSwitch消息。

Step 04 客户端GameStart模块收到广播的消息,调用onNotifyMatchTeamBaseInfo函数进行切换界面。

onNotifyMatchTeamBaseInfo代码如下所示。

TeamMatch绑定了组队界面的根节点,通过SetActive进行激活,显示队伍匹配界面,如图3-17所示。

图3-17

组队界面中包含“开始匹配”与“退出队伍”两个功能键,与之对应的是UI事件——OnMatch与OnQuitTeam。这两个UI响应事件的功能都是通知服务器客户端当前的状态,服务器端更新对应客户端的状态。因此,每个客户端界面的切换都是通过服务器消息来驱动的。OnQuitTeam代码如下所示。

◎匹配

返回匹配的消息(GSToGC.MsgID.eMsgToGCFromGS_NotifyMatchTeamSwitch)同上节相同,通过MessageHandler的解码处理,并通过内部消息GameEventEnum.UserEvent_NotifyMatchTeamSwitch广播,最终在GameStart中用onNotifyMatchTeamSwitch函数来处理。消息广播带有一个bool类型的参数,内容决定显示或隐藏匹配界面。MatchSearching是匹配界面的根节点。在GmaStart中定义,并在外部进行指定。代码如下所示。

在匹配过程中,为界面中的“取消匹配”按钮Click绑定事件处理函数OnCancelBtn,单击按钮向服务器发出申请取消匹配消息GCToCS.AskStopMatch,服务器接收到消息后,处理并转发相同消息给当前客户端。

匹配计时

匹配等待界面包含两部分信息:时长与匹配人数。时长的更新就是定时改变显示的数字,时长关联的Label变量mTimeLabel在GameStart中定义后,在场景中进行关联绑定。时间更新还需要float类型的变量mStartTime负责计时,显示时间格式MM:SS,通过工具类CTools中的ShowCount函数将float的时间进行转换。代码如下所示。

只有显示匹配界面后才开始计时,所以需要定义一个变量mIsDownTime作为计时器的开关。在处理匹配界面显示的函数中打开或者关闭开关,同时将mStartTime置为0。

匹配人数

匹配界面的另一部分显示当前已经匹配上的人数,人数的变化是服务器端通知客户端。界面只是显示匹配好的人数,显示匹配数量的Label变量定义和绑定同匹配计时,当客户端接收到eMsgToGCFromGS_NotifyBattleMatherCount的消息时,最终通过GameStart中的onNotifyBattleMatherCount的函数来处理显示。代码如下所示。

BattleMatcherCount消息体中包含着当前匹配上的人数和最大个数。客户端将消息中的内容格式化后显示。