UNITY 網(wǎng)絡(luò)游戲開發(fā)

本期內(nèi)容:unity網(wǎng)絡(luò)游戲開發(fā)。
關(guān)鍵字:操作同步,防外掛,斷線重連,弱網(wǎng)設(shè)計(jì)。
課程目標(biāo):為單機(jī)游戲,增加網(wǎng)絡(luò)對戰(zhàn)功能。
學(xué)完本課程之后,收獲網(wǎng)游開發(fā)的核心技術(shù)。
## 本期內(nèi)容建議結(jié)合視頻觀看
視頻觀看地址:[點(diǎn)擊進(jìn)入]
之前的教程,講解了從零開發(fā)戰(zhàn)棋游戲(單機(jī))
(基于AssetBundle)資源管理和更新
(基于ILRUNTIME)C#代碼熱更

大家也對之前的課程作出了大力的支持
比如**點(diǎn)贊**,**評論,收藏,轉(zhuǎn)發(fā)**
正因如此:本期視頻誕生了
從單機(jī)到網(wǎng)絡(luò),最核心的兩步
1:增加網(wǎng)絡(luò)通信模塊
2:設(shè)計(jì)同步方案
網(wǎng)絡(luò)框架用ET6,原因:
知名度高,上線項(xiàng)目做過驗(yàn)證,C#語言開發(fā)
支持分布式部署
因?yàn)?/p>
單臺電腦無論性能再高,CPU和內(nèi)存都有上限
所以
分布式可以讓多臺電腦協(xié)同工作,從而突破硬件上限
容納更多人數(shù)
服務(wù)器采用C#編程
客戶端的代碼可被后端重用,因此減少了后端的開發(fā)時(shí)間
ET6有著很多功能和特色
課程的側(cè)重點(diǎn)在于網(wǎng)絡(luò)同步和設(shè)計(jì)
在這里只是講需要使用到的部分
比如:(網(wǎng)絡(luò)協(xié)議生成,網(wǎng)絡(luò)通信模塊)
關(guān)于ET6更多的內(nèi)置功能
大家可以進(jìn)入ET官網(wǎng),學(xué)習(xí)和查閱
[https://et-framework.cn/](https://et-framework.cn/)
目錄:
## 1:ET的搭建部署
?參照ET-master\Book\1.1運(yùn)行指南.md?
演講視頻z01(2021-11-13制作完成)
?
## 2:前后端相互發(fā)送“HelloWorld”
消息的發(fā)送,請求,廣播
? ? 演講視頻z02(2021-11-13制作完成)
前端向后端發(fā)送消息"helloWorld"
protobuf協(xié)議生成
調(diào)用session.send接口
后端收到消息后顯示在控制臺
配置Nlog.config
前端向后端 請求 回復(fù)
后端向前端發(fā)送消息"helloWorld"
## 3:分布式
分布式的應(yīng)用非常廣泛,比如
1:讓多臺電腦協(xié)同工作,突破硬件性能上限
2:單個(gè)服務(wù)器損壞時(shí),備用服務(wù)器進(jìn)行支援
3:根據(jù)玩家的地區(qū)和延時(shí),選擇網(wǎng)速最優(yōu)的服務(wù)器等等
功能模塊的分布,本質(zhì)上是為了更好的運(yùn)營和管理
本節(jié)通過制作聊天功能,學(xué)習(xí)ET6分布式的開發(fā)流程

劃分聊天模塊,編輯ET-master/Excel/StartSceneConfig.xlsx
SceneType.cs增加聊天服枚舉 Chat
SceneFactory.cs增加聊天服所需組件UnitComponent
登錄聊天服
發(fā)送聊天信息
廣播聊天信息
分布式處理業(yè)務(wù)消息的模板

## 4:整合戰(zhàn)棋客戶端和ET6
之前我們已經(jīng)用U3D2019完成了戰(zhàn)棋游戲的客戶端框架
但是
因?yàn)镋T運(yùn)行指南第2條明確表示需要U3D2020版本
所以
客戶端進(jìn)行了2019->2020版本升級,
大部分是編輯器工具的API需要升級
(比如A星地圖編輯器)
ET6的分支版本選擇
因?yàn)樾枰玫絚#熱更,用到的是ET6的支持ILRUNTIME版本
[https://www.lfzxb.top/et-6-with-ilruntime/](https://www.lfzxb.top/et-6-with-ilruntime/)
并且按照ET6的框架要求,對項(xiàng)目重新進(jìn)行了目錄調(diào)整
(詳見本文的客戶端環(huán)境搭建)
這次增加PVP模式的實(shí)現(xiàn)策略是設(shè)計(jì)模式中的 開閉原則
少修改或不做修改的情況下實(shí)現(xiàn)需求
這樣做的好處是新需求實(shí)現(xiàn)時(shí)不會影響到以前的功能
框架的初始化的拓展:
ET的啟用入口在Init.cs腳本
所以增加 InitSlg.cs,增加了戰(zhàn)棋框架必要的初始化方法
比如C#熱更ILRUNTIME框架需要用到的語法適配
開發(fā)效率:
InitSlg下ilruntimeMode勾選策略,對開發(fā)效率很重要
開發(fā)模式不要勾選,有利于開發(fā)效率,錯(cuò)誤信息的查看
發(fā)布移動(dòng)平臺時(shí)才勾選
## 5:客戶端對戰(zhàn)系統(tǒng)的協(xié)議處理
第一季的開發(fā)過程中,我們已經(jīng)熟練的掌握了戰(zhàn)棋游戲的業(yè)務(wù)邏輯
要加入網(wǎng)絡(luò)對戰(zhàn),雖然有很多事情需要解決
但只要選擇關(guān)鍵點(diǎn)切入,很多事情都會水到渠成
協(xié)議就是切入開發(fā)的關(guān)鍵點(diǎn)
第一步:定制協(xié)議
戰(zhàn)斗場景生成,移動(dòng),攻擊,技能,行動(dòng)順序。
戰(zhàn)斗場景生成 包含 初始化信息,比如人物位置,技能,屬性,門派等
移動(dòng) 包含 起始id , 終點(diǎn)id , 2個(gè)字段
攻擊 包含 起始id , 終點(diǎn)id , 目標(biāo)id,3個(gè)字段
技能 包含 起始id ,終點(diǎn)id , 目標(biāo)id, 技能id,4個(gè)字段
行動(dòng)順序 包含 門派信息
第二步實(shí)現(xiàn)協(xié)議的處理;
為了提高開發(fā)效率,客戶端先本做好本地測試,然后才接入服務(wù)端。
這樣就不用為了測試單個(gè)功能反復(fù)打開服務(wù)端。
詳見視頻.......
## 6:后端對接-跑通對戰(zhàn)流程
服務(wù)器配置了比賽服,比賽對戰(zhàn)的相關(guān)業(yè)務(wù)由它負(fù)責(zé)
這就意味了比賽服需要進(jìn)行戰(zhàn)斗計(jì)算得出結(jié)果
用于處理客戶端的斷線重連,防作弊,勝負(fù)判斷等
戰(zhàn)斗功能都在客戶端里寫好了,只要把相關(guān)的代碼 引用,或者復(fù)制到服務(wù)器,稍作修改即可。
雖然服務(wù)器和客戶端都是C#語言,但是對于服務(wù)器來說:對戰(zhàn)過程是不需要?jiǎng)赢嬓Ч?/p>
所以只要把動(dòng)畫效果相關(guān)的代碼處理掉即可
方法一: #if !SERVER? 利用宏剔除服務(wù)器不需要的代碼
比如我們的技能系統(tǒng),原封不動(dòng)的引用了客戶端的代碼文件
有藍(lán)色箭頭的C#文件,代表文件引用

方法二:代碼拷貝到服務(wù)器后,刪除掉不必要?jiǎng)赢嫶a
沒有藍(lán)色箭頭的C#文件,則是修改
因?yàn)橥ㄟ^宏來區(qū)分代碼,在模塊比較復(fù)雜的時(shí)候代碼的閱讀性會下降

開發(fā)者根據(jù)項(xiàng)目的具體情況做出選擇即可
服務(wù)器解決了戰(zhàn)斗模塊之后,
再結(jié)合第3課的聊天服務(wù)的案例,
同步方案的到這里已經(jīng)成形了
剩下的問題,只是工作量
最終設(shè)計(jì)整體流程

## 7: 登錄超時(shí)和斷線重連
客戶端處理 鏈接錯(cuò)誤和鏈接超時(shí),斷線重連
斷線模擬工具
模擬現(xiàn)實(shí)中,坐在車上進(jìn)入信號不好的隧道,30秒后恢復(fù)了網(wǎng)絡(luò)。
怎么做呢?
首先找到當(dāng)前客戶端連接的網(wǎng)關(guān)端口
要么10003,要么10004

或者,用客戶端打印出連接的端口號

用弱網(wǎng)工具把網(wǎng)關(guān)的收發(fā)數(shù)據(jù)強(qiáng)行丟包,在這期間服務(wù)器和客戶端是無法進(jìn)行通信的
30秒后,客戶端出現(xiàn)掉線重連界面,關(guān)閉丟包測試。
客戶端會重新連接到服務(wù)器,重新同步狀態(tài)。
阻斷10004端口的消息
tcp.DstPort == 10004 or tcp.SrcPort == 10004
阻斷10003和10004端口
(tcp.DstPort <=10003 or tcp.SrcPort == 10003)?
or
?(tcp.DstPort <=10004 or tcp.SrcPort == 10004)

## 9:弱網(wǎng)測試
兩個(gè)真實(shí)客戶端的弱網(wǎng)環(huán)境測試
網(wǎng)絡(luò)傳輸協(xié)議一般有兩種,可靠的(tcp)和不可靠的(upd)
使用不同的協(xié)議,客戶端處理細(xì)節(jié)的方式也會有所不同
upd在一些比較老的幀同步項(xiàng)目會比較常見,需要處理丟包和順序打亂的問題
ET6使用的是KCP協(xié)議,可靠性傳輸,會確保消息不丟失,順序不會被打亂
測試:
為了快速測試功能,我們先關(guān)閉第二季的資源熱更框架
模式下的打包設(shè)置
勾選Main場景Init Slg 的ab包只通過streaming 模式加載

打開2個(gè)客戶端,弱網(wǎng)測試截?cái)?/p>
通過丟包測試可以得出結(jié)論,KCP協(xié)議丟包之后會進(jìn)行消息重發(fā),確??蛻舳耸盏?/p>

## 安全和防外掛設(shè)計(jì)
因?yàn)槲覀兊脑O(shè)計(jì)是操作同步,大部分的計(jì)算都在客戶端里
假如玩家使用外掛修改客戶端的數(shù)值,怎么應(yīng)對呢?
客戶端修改了攻擊力
服務(wù)器和客戶端對比關(guān)鍵數(shù)值
只要不一致,客戶端同步服務(wù)器的數(shù)值


客戶端修改可控單位:
服務(wù)器先做邏輯判斷再處理


修改了移動(dòng)力:技能范圍
因?yàn)橛?jì)算過程涉及了A星算法,想要安全驗(yàn)證,就必須實(shí)現(xiàn)服務(wù)器A星的算法
因?yàn)檫@已經(jīng)是服務(wù)器開發(fā)的進(jìn)階部分了,已經(jīng)超出課程的討論范圍了
## 安卓發(fā)布,真機(jī)測試
測試內(nèi)容, 移動(dòng)平臺,熱更,網(wǎng)絡(luò)
1:修改服務(wù)器的IP為局域網(wǎng)或者外部的地址
配置文件Excel/StartMachineConfig

2:生成代碼和素材資源
?U3D 頂部菜單-Window->AssetBundle Browser->選擇安卓平臺->Build
? U3D 頂部菜單->資源部署->生成資源清單
生成的資源在../AssetBundle/Android
3:構(gòu)建資源服務(wù)
拷貝AssetBundle/Android目錄到 Nginx/html
(Nginx軟件,可以搭建HTTP服務(wù)器)
cmd->運(yùn)行Nginx
4:配置客戶端
修改登錄服務(wù)IP
把生成的全部資源 拷貝到StreamingAssets
(如需靈活控制首包體積,或加密資源,詳見第二季內(nèi)容)

3:發(fā)布安卓平臺


測試模式,使用mono,不勾選IlruntimeMode,打包時(shí)間快
發(fā)布模式,根據(jù)平臺要求勾 是否使用IL2CPP,IlruntimeMode,打包時(shí)間慢3倍
比如上線谷歌平臺,因?yàn)槠脚_政策原因,只能是用64位+IL2CPP
假如是ILRUNTIME模式,需要先成一次CLR綁定,
可以避開運(yùn)行時(shí)的一些錯(cuò)誤
最終可以通過網(wǎng)絡(luò)進(jìn)行對戰(zhàn)

## 第四季:視頻講解**完**
下面是備課階段整理的資料,可以選擇觀看
## 客戶端環(huán)境搭建
熱更程序集的生成和《u3d 代碼熱更解決方案 ILruntime》有所不同
天地劫項(xiàng)目的熱更代碼是用VS解決方案發(fā)布的,和U3D解決方案分離(2個(gè)解決方案)
ET框架把Asset下的若干個(gè)目錄設(shè)置為程序集,熱更代碼發(fā)布是由腳本控制(1個(gè)解決方案)
ET6熱更程序集工作流 :
優(yōu)點(diǎn)
分散的目錄設(shè)置為程序集,**提升U3D編譯速度**
**方便編輯器插件的開發(fā)**(熱更和主工程的程序集在編輯器下都可以被U3D編輯器加載)
缺點(diǎn):
新手會經(jīng)常遇到代碼提示缺少引用,是因?yàn)橐藐P(guān)系沒設(shè)置好。
所以需要我們熟悉項(xiàng)目的代碼,才能正確設(shè)置每個(gè)程序集之間的引用關(guān)系。
分離解決方案的工作流
優(yōu)缺點(diǎn)和ET形成反差
最終為了能夠兼容ET6的開發(fā)流程
?戰(zhàn)旗代碼的目錄重新改動(dòng),便于適應(yīng)ET6的開發(fā)工作流
所以我們要把戰(zhàn)旗的代碼目錄設(shè)置為不排除(去掉目錄名字的~)
并且按照ET框架進(jìn)行調(diào)整目錄(插件放到第三方目錄,編輯相關(guān)的目錄放到Editor下)
IL2CPP發(fā)布時(shí),最好先用ILRUNTIME的 生成CRL綁定和注冊,避免運(yùn)行時(shí)的各種錯(cuò)誤
提升開發(fā)效率的配置:
**ILRuntimeMode** 表示熱更的C#代碼采用ilruntime模式
**開發(fā)模式下不打鉤,方便斷點(diǎn)和異常信息的查看**

## 客戶端的網(wǎng)絡(luò)消息處理
首先需要了解三個(gè)概念:
請求:需要回復(fù)? ? ? ? ?舉例:(詢問服務(wù)器的名字)?
發(fā)送:不需要回復(fù)? ? ? 舉例:(把名字告訴服務(wù)器)
通知:被動(dòng)收到消息? ?舉例:(服務(wù)器主動(dòng)把名字說出來)
所以知道服務(wù)器的名字有三種情況
客戶端問了
客戶端沒問服務(wù)器自己說了出來
其他客戶端問了,服務(wù)器把名字告訴了所有人(廣播)
至于什么是廣播?那是服務(wù)端的工作,前端可以無須理解
天地劫案例移動(dòng)指令同步方案:
方案一
客戶端A 點(diǎn)擊鼠標(biāo)后 發(fā)送 移動(dòng)坐標(biāo)指令
服務(wù)端通知 客戶端B
客戶端B 收到指令 更新人物坐標(biāo)
方案二
客戶端A 點(diǎn)擊鼠標(biāo)后 發(fā)送 移動(dòng)坐標(biāo)指令
服務(wù)器收到消息后校驗(yàn)移動(dòng)坐標(biāo)的合法性,假如作弊,封號
服務(wù)端通知 客戶端B
客戶端B 收到指令 更新人物坐標(biāo)
方案三
客戶端A 點(diǎn)擊鼠標(biāo)后 請求移動(dòng)?
服務(wù)端計(jì)算尋路的路徑后?
廣播通知 A.B
客戶端A,B 收到指令 更新人物坐標(biāo)
方案一更高性能,是幀同步首選,至于幀同步的防作弊,有空我們再單獨(dú)開一個(gè)章節(jié)講解
方案二,三 都可以作為天地劫的解決方案
## ET的ECS組件開發(fā)到底是不是前端需要的?
簡單來說ECS就是組件式開發(fā)+三層架構(gòu)(MVC)
站在前端的角度來說U3D Monobehavior就擁有了組件式的開發(fā)能力
那么ET為什么還要開創(chuàng)自己的組件開發(fā)方式?
原因有很多
比如:ET的設(shè)計(jì)出發(fā)點(diǎn)是打造一套代碼“前后端通用”,
考慮到后端脫離了U3D引擎自然不能使用Monobehavior
站在ILRUNTIME代碼熱更的角度:
不使用Monobehavior,解決了熱更代碼跨域繼承的性能問題
??
? 《U3D天地劫》**完成的項(xiàng)目**,目的是**增加網(wǎng)絡(luò)狀態(tài)同步**
??
? 所以我們需要問自己
? 項(xiàng)目需不需要前后端代碼復(fù)用?
? 需不需要MVC方式開發(fā)?
?你是否愿意花額外的時(shí)間把已經(jīng)寫好的游戲進(jìn)行框架重構(gòu)?
我們的需求是,用**最少的時(shí)間成**本去完成這件事
如果使用ET的組件開發(fā)思想,需要大量代碼的重構(gòu),必定要額外花費(fèi)時(shí)間。
所以權(quán)衡利弊之后,最終做出選擇
我們的游戲代碼還是保持原來的風(fēng)格,ET只是作為一個(gè)網(wǎng)絡(luò)通信庫來使用
僅僅是需要ET**收發(fā)消息功能**而已
ET組件式開發(fā)的在本課程里盡量少用或者不用
只保留網(wǎng)絡(luò)協(xié)議處理的核心用法(比如廣播消息的接收)
## 匹配對戰(zhàn)請求設(shè)計(jì)
前后端商量協(xié)議格式
客戶端的請求C2G_MatchPvp? (匹配其他玩家)
服務(wù)器的返回G2C_MatchPvp? ? (匹配操作結(jié)果)
直到匹配人數(shù)為2,服務(wù)器通知:M2C_EnterPvp(對局開始)??
詳細(xì)過程
客戶端點(diǎn)擊匹配對戰(zhàn)? ?發(fā)出請求C2G_MatchPvp? ?
?C=Client=客戶端,G=Gate=網(wǎng)關(guān)
至于網(wǎng)關(guān)是啥前端不用理解,一般由后端定制
所以這條消息就是代表 客戶端 發(fā)給 服務(wù)器的 網(wǎng)關(guān)服
進(jìn)入匹配狀態(tài) 給客戶端發(fā)回 G2C_MatchPvp? ?
匹配玩家數(shù)等于2,服務(wù)器派發(fā)通知 M2C_EnterPvp(對戰(zhàn)開始)
??
? 前端 需要關(guān)注前綴有C的協(xié)議
? C2G_******? ? ? ?G2C_*******? ? ? ??
? C2M_******? ? ? M2C_*******
服務(wù)端關(guān)注的協(xié)議的比較多
因?yàn)樗枰幚矸植际降膶?shí)現(xiàn)
需要處理客戶端的消息 C2*? ?,也要處理服務(wù)器之間的消息? G2* , *2G
例如 C2G_LoginGate,R2G_GetLoginKey,G2M_CreateUnit
//網(wǎng)關(guān)和客戶端的消息,網(wǎng)關(guān)和地圖服的分布處理消息 等
當(dāng)然客戶端無需理解服務(wù)器的處理過程
U3D 實(shí)現(xiàn)
發(fā)送 Session.Send(new T1(msg="你好服務(wù)器"))
請求? T msg= await Session.Call(new T1(msg="你好服務(wù)器")) as T;?
msg則是服務(wù)器返回的消息
//msg.info="你好客戶端"
消息的廣播通過ET的事件架構(gòu)訂閱
class G2C_HelloWolrd_Handler:AMHandler<G2C_HelloWolrd>
{
? ? ? Run(message){
? ? ? ? ///message=你好客戶端,服務(wù)器在給你推送消息。
}
{

指令同步:移動(dòng)
A客戶端轉(zhuǎn)發(fā)**指令50到35**,服務(wù)器廣播該消息,B客戶端收到后播放動(dòng)畫
這里只是轉(zhuǎn)發(fā)指令
## 客戶端修改移動(dòng)數(shù)值怎么處理?
服務(wù)器會返回操作結(jié)果,假如指令不合法,會強(qiáng)制客戶端重新同步數(shù)據(jù)
大家可以看下圖的協(xié)議設(shè)計(jì)


攻擊邏輯的設(shè)計(jì)
MMO:發(fā)出攻擊請求,服務(wù)器返回?cái)?shù)據(jù),一般會包含哪些人物被攻擊,受到了多少傷害,以及派生的效果
天地劫:發(fā)出攻擊請求,客戶端自行計(jì)算傷害以及派生效果。
為什么要這樣設(shè)計(jì)呢?因?yàn)榈谝患镜恼n程已經(jīng)開發(fā)完了整套游戲的邏輯
服務(wù)器的代碼只是在客戶端移植過去的。所以計(jì)算結(jié)果不用服務(wù)器另外通知
而且還能減少數(shù)據(jù)傳輸?shù)拈_銷,攻擊的協(xié)議只包含3個(gè)int參數(shù)from,to,target?
因?yàn)榭蛻舳俗孕杏?jì)算了結(jié)果,這里為了防止惡意修改數(shù)值,比如攻擊力=9999
所以要做操作指令安全驗(yàn)證:
攻擊指令發(fā)出后后(比較客戶端和服務(wù)器的md5碼)
如果兩邊不同步,客戶端同步服務(wù)器數(shù)據(jù)
由于這些計(jì)算大部分都是服務(wù)器的工作,所以前端無須關(guān)注
課程為了**前后端細(xì)分**
課程會做出**策劃設(shè)定限制**(PVP模式,攻擊距離只能為0-1,不能配備AOE技能)
因?yàn)檫@些設(shè)定包含了大多屬于后端的工作,前端是不需要學(xué)習(xí)的,
所以我們會在另開一遍服務(wù)器的教程,詳細(xì)講安全數(shù)據(jù)的驗(yàn)證和實(shí)現(xiàn)
下圖結(jié)果顯示,每次指令執(zhí)行后,都會比較狀態(tài)同步碼來確保數(shù)據(jù)永遠(yuǎn)以服務(wù)端的為準(zhǔn),
實(shí)際開發(fā)中可以生成 MD5碼,減少數(shù)據(jù)包的大小


## 如何編寫前后端通用的代碼
下圖是服務(wù)器的代碼,Skill目錄下的引用了客戶端的技能模塊

可以看到在加血技能釋放時(shí),服務(wù)器只需要數(shù)據(jù)的計(jì)算,不需要特效部分

## 掉線檢測
在網(wǎng)絡(luò)不好的情況下,數(shù)據(jù)收發(fā)會有延時(shí),或者丟失。
ET6內(nèi)置了心跳包檢測機(jī)制,默認(rèn)是超時(shí)是30秒,30秒內(nèi)收不到服務(wù)器回應(yīng)視為斷線

## 掉線重連
斷線一般發(fā)生在兩種情況,用戶強(qiáng)制關(guān)閉的客戶端?;蛘咦谲嚿?,進(jìn)入隧道(瞬間的網(wǎng)絡(luò)不好)
第一種情況的處理:由服務(wù)器端編寫當(dāng)用戶重新登錄時(shí),重新回到戰(zhàn)場的邏輯
第二種情況的處理:訂閱連接超時(shí)事件,超時(shí)后進(jìn)行重新登錄和狀態(tài)同步,
假如重新登錄還是超時(shí),則放棄重連,返回登錄界面
用clumsy弱網(wǎng)測試工具。進(jìn)行丟包測試

## 丟包處理
因?yàn)镋T采用了kcp協(xié)議,即使丟包也會重傳保證客戶端能收到
?弱網(wǎng)測試工具clumsy。丟包測試通過
?**所以ET6框架不需要考慮丟包問題**
下面講述的是前端在面對使用UDP廣播的服務(wù)端時(shí)如何處理丟包的處理方法。
(畢竟工作中不是每個(gè)項(xiàng)目都會用到kcp協(xié)議)
坐在車上的我們即將進(jìn)入隧道,通過時(shí)間是5秒,然后恢復(fù)了網(wǎng)絡(luò)。
在這短短的5秒里對方剛好又做了移動(dòng)操作。
而客戶端卻因?yàn)樗淼览锞W(wǎng)絡(luò)不好丟了這條指令.
因?yàn)榉?wù)器消息的廣播采用UDP協(xié)議,不確保客戶端能收到消息。
那也就說,我們無法得知我們自己是否丟包了。
由于丟包時(shí)長不足30秒,所以無法采用斷線重連的處理方式,
所以,因?yàn)橹皇莵G了一個(gè)移動(dòng)消息包,游戲狀態(tài)得不到同步。
解決方案:服務(wù)器連續(xù)發(fā)送消息包號,客戶端存起來,
假如的客戶端的包號+1和 服務(wù)器的對不上,我們就知道丟包了

最后我們對項(xiàng)目進(jìn)行弱網(wǎng),無網(wǎng)測試通過。
課程關(guān)鍵字:
unity網(wǎng)絡(luò)框架,unity網(wǎng)絡(luò)通信,unity網(wǎng)絡(luò)同步,unity網(wǎng)絡(luò)實(shí)戰(zhàn),unity網(wǎng)絡(luò)游戲教程,unity網(wǎng)絡(luò)游戲開發(fā),unity網(wǎng)絡(luò)實(shí)戰(zhàn)