帧同步学习记录
幀同步
參考鏈接
- 細談網(wǎng)絡(luò)同步在游戲歷史中的發(fā)展變化(上)
- 細談網(wǎng)絡(luò)同步在游戲歷史中的發(fā)展變化(下)
網(wǎng)易雷火
- cocos2dx lua socket 使用
- cocos creator 項目總結(jié)二(戰(zhàn)斗幀同步解析)
- 2 天做了個多人實時對戰(zhàn),200ms 延遲竟然也能絲滑流暢?
不是標題黨,講的非常完善清晰,而且還有狀態(tài)同步的例子
- Unity游戲開發(fā) 幀同步戰(zhàn)斗框架 理論篇
- Unity游戲開發(fā) 幀同步戰(zhàn)斗框架 框架篇
兩篇學(xué)會幀同步
-
Unity幀同步解決方案(一)
-
Unity幀同步解決方案(二)
-
Unity 游戲開發(fā)總結(jié)
大佬的專欄,還有很多Unity的知識 -
《王者榮耀》技術(shù)總監(jiān)復(fù)盤回爐歷程:沒跨過這三座大山,就是另一款MOBA霸占市場了
一. 簡介
幀同步和狀態(tài)同步是目前最常用的游戲同步設(shè)計。它們并不互斥,可以一起相輔相成的出現(xiàn)于同步邏輯中。
下圖來自 Unity游戲開發(fā) 幀同步戰(zhàn)斗框架 理論篇
二. 客戶端邏輯
幀同步的邏輯都在客戶端,所以首要保證的是不同客戶端同一幀內(nèi)的計算結(jié)果一定要相同。
- 可控的客戶端的邏輯
- 邏輯顯示分離
- 可控的隨機
1).客戶端幀同步邏輯
unity游戲開發(fā) 幀同步戰(zhàn)斗框架 框架篇
幀同步的邏輯全都在客戶端計算,必須保證每個客戶端相同幀的計算結(jié)果是一樣的。
要完全控制客戶端的計算流程,比如,移動,碰撞,動畫事件,延遲處理(等待s秒)等。
渲染因為跟不同硬件設(shè)備以及引擎有著相對較強的關(guān)聯(lián),所以客戶端會設(shè)計成邏輯與顯示分離。
渲染部分可以交給引擎提供的更新,而邏輯更新必須由客戶端實現(xiàn)的Update控制。
1.主要邏輯
Update(delta){事件幀邏輯幀 }UpdateRender(delta){渲染幀 }- 事件幀:幀同步的幀,包含某段時間內(nèi)所有玩家的操作
- 邏輯幀:游戲的所有邏輯
- 渲染幀:顯示部分的更新,比如坐標
1個事件幀 = n個邏輯幀 = n*m 個渲染幀
2.統(tǒng)一時間間隔
事件幀和邏輯幀是一起更新的,邏輯幀間隔小于等于事件幀。使用更小的間隔來判斷 deltaTime。
要注意的是,Update 傳入的間隔時間不是固定的,是變化的。比如 前臺 -> 后臺,后臺 -> 前臺。這時候傳入的時間就會很大。
#define 時間幀更新間隔 #define 邏輯幀更新間隔Update(delta){delta 計算if(delta < 邏輯幀時間間隔)return;間隔x次邏輯幀 = math.min(delta/邏輯幀更新間隔, 剩余事件幀數(shù)量)for(ini i = 0;i < 間隔x次邏輯幀;i ++){//事件幀Event(邏輯幀更新間隔)//邏輯幀Logic(邏輯幀更新間隔)} }Event(deltaTime){更新次數(shù) + 1if(更新次數(shù) < n) returnif(是否有事件幀) {邏輯幀更新次數(shù) = 0return;}//分發(fā)更新次數(shù) = 0邏輯幀更新次數(shù) = n }Logic(deltaTime){if(邏輯幀更新次數(shù) <= 0) return;邏輯幀更新次數(shù) - 1//進行邏輯幀更新,,, }傳入的間隔時間經(jīng)過處理,每次更新間隔就是邏輯幀間隔時間。這樣確保了即使是不同客戶端,不同間隔時間,每幀的更新也一定是同樣的間隔時間。
3.斷線重連和回放
回放:幀同步天然支持回放,把整局游戲按幀回放即可。
斷線重連:想想回放的邏輯,追幀加速即可。
2).邏輯顯示分離
1.保證不同客戶端結(jié)果相同
比如,動畫系統(tǒng)。
游戲中的行為,交互都是跟動作有關(guān)的。
比如攻擊動畫在 x 秒的動作打開碰撞,x秒的動作關(guān)閉碰撞。在x秒的時候生成一道劍氣等等。如果你的動畫系統(tǒng)不在你的控制之中,那么有可能在不同的設(shè)備上,不正確的時間點進行對應(yīng)的行為。
目前的做法是用一組技能點隊列來控制動畫,而不是動畫的某一幀來觸發(fā)事件。每次更新的時候進行技能點的檢測,以及生成對應(yīng)行為。
2.平滑卡頓
幀同步只會同步操作,而且一般來說手機端都是用 20-30 網(wǎng)絡(luò)幀同步來制作的。
30幀基本就是人眼卡頓的極限了。顯示和邏輯分離則仍可以使用30幀以上的渲染更新,以及使用插值的來平滑卡頓。
3.作弊檢測
每隔x幀,各個客戶端向服務(wù)器端發(fā)送檢驗數(shù)據(jù),如果都一樣則通過,數(shù)據(jù)異常則可能是bug或作弊。
3).可控的隨機
幀同步的邏輯都是客戶端在計算的,所以得保證每個客戶端計算的結(jié)果要一致。那么對于一些不確定的邏輯就要給予確定性。
1.隨機數(shù)
可以參考如下鏈接的做法:
- Unity游戲開發(fā) 幀同步戰(zhàn)斗框架 理論篇
- 隨機數(shù)生成算法
目前項目是很簡單粗暴的做法。隨機生成了一個 x 長度的隨機隊列,每次隨機數(shù)按順序從里面取,取到隊尾再回頭取。
如果隨機數(shù)隊列有變化,那之前的回放就不可查看了。
2.浮點數(shù)
浮點數(shù)帶來的誤差,比如計算概率屬性(暴擊傷害,百分比治療等等),碰撞(小數(shù)帶來的碰撞誤差),以及循環(huán)增減時的低位浮點數(shù)累計問題等。
基本做法:
混合使用即可。目前只用了第二種,計算結(jié)果(屬性變化,位置移動等)向下取整( math.floor() )。
3.map和array
同樣,常用的字典類型也基本不能使用,應(yīng)該都用隊列這種固定順序的數(shù)據(jù)結(jié)構(gòu)來存儲。
但是字典類型方便查找,都用隊列肯定會降低查找效率以及代碼的工整性。
解決的方法就是實現(xiàn)一個數(shù)據(jù)結(jié)構(gòu),內(nèi)部同時使用 字典和隊列 來維護當前數(shù)據(jù),實現(xiàn)這組數(shù)據(jù)的增刪改查等邏輯即可。
4).預(yù)測/回滾
預(yù)測、回滾、快照是一起出現(xiàn)的,因為幀同步的邏輯延遲和網(wǎng)絡(luò)固定的延遲,以及數(shù)據(jù)的拆解和gc等等各種因素。
實際同步肯定會有些許的卡頓。常用的方法就是客戶段對當前的邏輯進行預(yù)測(1幀),先進行當前幀的模擬。并且存儲當前游戲的快照。
如果服務(wù)器發(fā)送下來的操作導(dǎo)致預(yù)測結(jié)果出錯,則快速回滾到前一幀,并執(zhí)行正確的邏輯,回到當前幀再進行下一幀的預(yù)測。
暫時還沒做到這塊,對快照存儲還有些疑問。具體概念參考如下文章:
2 天做了個多人實時對戰(zhàn),200ms 延遲竟然也能絲滑流暢?
三.網(wǎng)絡(luò)處理
1).TCP/UDP
TCP是一般使用的法案。但想要快肯定用UDP,目前安全的UDP庫也很多,可以直接使用。
四.調(diào)試工具
總結(jié)
- 上一篇: python浏览器自动化测试仪器_【松勤
- 下一篇: 国家测绘地理信息局黑龙江基础地理信息中心