本期用的是ET6+ILRUNTIME开发
热更程序集的生成和《u3d 代码热更解决方案 ILruntime》有所不同
天地劫项目的热更代码是用VS解决方案发布的,和U3D解决方案分离(2个解决方案)
ET框架把Asset下的若干个目录设置为程序集,热更代码发布是由脚本控制(1个解决方案)
ET6热更程序集工作流 :
优点
分散的目录设置为程序集,提升U3D编译速度
方便编辑器插件的开发(热更和主工程的程序集在编辑器下都可以被U3D编辑器加载)
缺点:
新手会经常遇到代码提示缺少引用,是因为引用关系没设置好。
所以需要我们熟悉项目的代码,才能正确设置每个程序集之间的引用关系。
分离解决方案的工作流
优缺点和ET形成反差
最终为了能够兼容ET6的开发流程
战旗代码的目录重新改动,便于适应ET6的开发工作流
所以我们要把战旗的代码目录设置为不排除(去掉目录名字的~)
并且按照ET框架进行调整目录(插件放到第三方目录,编辑相关的目录放到Editor下)
IL2CPP发布时,最好先用ILRUNTIME的 生成CRL绑定和注册,避免运行时的各种错误
首先需要了解三个概念:
请求:需要回复 举例:(询问服务器的名字)
发送:不需要回复 举例:(把名字告诉服务器)
通知:被动收到消息 举例:(服务器主动把名字说出来)
所以知道服务器的名字有三种情况
客户端问了
客户端没问服务器自己说了出来
其他客户端问了,服务器把名字告诉了所有人(广播)
至于什么是广播?那是服务端的工作,前端可以无须理解
天地劫案例移动指令同步方案:
方案一
客户端A 点击鼠标后 发送 移动坐标指令
服务端通知 客户端B
客户端B 收到指令 更新人物坐标
方案二
客户端A 点击鼠标后 发送 移动坐标指令
服务器收到消息后校验移动坐标的合法性,假如作弊,封号
服务端通知 客户端B
客户端B 收到指令 更新人物坐标
方案三
客户端A 点击鼠标后 请求移动
服务端计算寻路的路径后
广播通知 A.B
客户端A,B 收到指令 更新人物坐标
方案一更高性能,是帧同步首选,至于帧同步的防作弊,有空我们再单独开一个章节讲解
方案二,三 都可以作为天地劫的解决方案
简单来说ECS就是组件式开发+三层架构(MVC)
站在前端的角度来说U3D Monobehavior就拥有了组件式的开发能力
那么ET为什么还要开创自己的组件开发方式?
原因有很多
比如:ET的设计出发点是打造一套代码“前后端通用”,
考虑到后端脱离了U3D引擎自然不能使用Monobehavior
站在ILRUNTIME代码热更的角度:
不使用Monobehavior,解决了热更代码跨域继承的性能问题
《U3D天地劫》完成的项目,目的是增加网络状态同步
所以我们需要问自己
项目需不需要前后端代码复用?
需不需要MVC方式开发?
你是否愿意花额外的时间把已经写好的游戏进行框架重构?
我们的需求是,用最少的时间成本去完成这件事
如果使用ET的组件开发思想,需要大量代码的重构,必定要额外花费时间。
所以权衡利弊之后,最终做出选择
我们的游戏代码还是保持原来的风格,ET只是作为一个网络通信库来使用
仅仅是需要ET收发消息功能而已
ET组件式开发的在本课程里尽量少用或者不用
只保留网络协议处理的核心用法(比如广播消息的接收)
前后端商量协议格式
客户端的请求C2G_MatchPvp (匹配其他玩家)
服务器的返回G2C_MatchPvp (匹配操作结果)
直到匹配人数为2,服务器通知:M2C_EnterPvp(对局开始)
详细过程
客户端点击匹配对战 发出请求C2G_MatchPvp
C=Client=客户端,G=Gate=网关
至于网关是啥前端不用理解,一般由后端定制
所以这条消息就是代表 客户端 发给 服务器的 网关服
进入匹配状态 给客户端发回 G2C_MatchPvp
匹配玩家数等于2,服务器派发通知 M2C_EnterPvp(对战开始)
前端 需要关注前缀有C的协议
C2G_****** G2C_*******
C2M_****** M2C_*******
服务端关注的协议的比较多
因为它需要处理分布式的实现
需要处理客户端的消息 C2* ,也要处理服务器之间的消息 G2* , *2G
例如 C2G_LoginGate,R2G_GetLoginKey,G2M_CreateUnit
//网关和客户端的消息,网关和地图服的分布处理消息 等
当然客户端无需理解服务器的处理过程
U3D 实现
发送 Session.Send(new T1(msg=“你好服务器”))
请求 T msg= await Session.Call(new T1(msg=“你好服务器”)) as T;
msg则是服务器返回的消息
//msg.info=“你好客户端”
消息的广播通过ET的事件架构订阅
class G2C_HelloWolrd_Handler:AMHandler
{
Run(message){
///message=你好客户端,服务器在给你推送消息。
}
{
指令同步:移动
A客户端转发指令50到35,服务器广播该消息,B客户端收到后播放动画
这里只是转发指令
服务器会返回操作结果,假如指令不合法,会强制客户端重新同步数据
大家可以看下图的协议设计
攻击逻辑的设计
MMO:发出攻击请求,服务器返回数据,一般会包含哪些人物被攻击,受到了多少伤害,以及派生的效果
天地劫:发出攻击请求,客户端自行计算伤害以及派生效果。
为什么要这样设计呢?因为第一季的课程已经开发完了整套游戏的逻辑
服务器的代码只是在客户端移植过去的。所以计算结果不用服务器另外通知
而且还能减少数据传输的开销,攻击的协议只包含3个int参数from,to,target
因为客户端自行计算了结果,这里为了防止恶意修改数值,比如攻击力=9999
所以要做操作指令安全验证:
攻击指令发出后后(比较客户端和服务器的md5码)
如果两边不同步,客户端同步服务器数据
由于这些计算大部分都是服务器的工作,所以前端无须关注
课程为了前后端细分
课程会做出策划设定限制(PVP模式,攻击距离只能为0-1,不能配备AOE技能)
因为这些设定包含了大多属于后端的工作,前端是不需要学习的,
所以我们会在另开一遍服务器的教程,详细讲安全数据的验证和实现
下图结果显示,每次指令执行后,都会比较状态同步码来确保数据永远以服务端的为准,
实际开发中可以生成 MD5码,减少数据包的大小
下图是服务器的代码,Skill目录下的引用了客户端的技能模块
可以看到在加血技能释放时,服务器只需要数据的计算,不需要特效部分