1. 程式人生 > >手遊網絡遊戲Unity3D幀同步

手遊網絡遊戲Unity3D幀同步

一、        前言

 幀同步,根據wiki百科的定義是,一種對同步源進行畫素級同步顯示的處理技術,對於網路上的多個接入者,一個訊號將會通過主機同步傳送給其他人,並同步顯示在各個終端上。同步訊號可以是每幀的畫素資料,也可以是影響資料變化的關鍵事件資訊。

幀同步在網路遊戲中的應用,設計上有異於傳統的mmorpg遊戲,因為可以承載更大量的後臺計算,實現類單機的效果,所以可應用在類似射擊類、飛機類中實現彈幕計算或者格鬥類的高精度打擊體驗

本文將主要介紹下幀同步與傳統mmorpg設計框架的異同點以及相關的幾個設計方案,最後,深入展開對其中一種實現方案的分析,而相關的反外掛和斷線重連機制等技術難點暫不在本文討論。

二、        幀同步在遊戲中的應用

網路遊戲中,遊戲服務的架構大致可以分為2種模式,分別是cs模式和p2p模式

cs模式框架如1(c為客戶, GSS為遊戲狀態伺服器)

1,遊戲狀態伺服器(GSS)單獨部署,負責對網路上各個接入者提供服務,當GSS狀態發生變化時,將狀態同步傳送給各個接收者。

p2p模式框架如2(c為客戶,GSS為遊戲狀態伺服器):

圖2中,遊戲狀態伺服器存在於各個客戶主機上,遊戲狀態的改變直接來自於各個客戶端的輸入。

以上2個服務框架中,cs模式,由於GSS伺服器只有一個,遊戲狀態能保證絕對一致,但GSS可能同時服務上萬個玩家,由於機器效能以及網路頻寬等硬體資源限制,伺服器對大部分情況都無法進行非常嚴格的檢查和處理;p2p模式相對於cs模式,同時連線的玩家有限,所以可以進行比較精細的運算,可實現類似射擊類、飛機類的彈幕計算或者格鬥類的高精度打擊體驗,但是,由於端到端的通訊方式,隨著同時接入使用者的增加,通訊量呈指數級增長,所以,其對同時接入的數量上會限制得比較嚴格,適合少量同屏的競技類等遊戲。

p2p模式中,由於存在多份的GSS,如何保證各個GSS一致也需要特殊考慮,幀同步演算法在遊戲中的應用,主要就是為了解決p2p模式下的GSS一致性問題。實現原理是將遊戲處理細化為幀,對於每幀,在同樣的執行環境中,保證同樣的輸入的情況下,將得到同樣的輸出結果。

圖3中,初始狀態都為1,序列幀第二幀時,輸入加1操作,則狀態變為2,第三幀時無輸入,狀態不變,第四幀時,輸入加1操作,狀態變為3.對於同個執行環境的各個客戶端來說,相同的輸入狀況下,將得到相關的輸出結果,如4效果。

通常,為了使用者的輸入能及時的響應以及遊戲狀態的過度能夠平滑,會將GSS設定為20到30幀以上。並且,由於客戶端機器效能或者設定的差異,GSS的狀態無法與遊戲渲染幀實現一一對應,所以,GSS與表現層必須做到完全的分離,否則將因為某些細小的誤差被放大最終導致遊戲出現完全不同的結果。

5,非確定的渲染層的輸出,完全由GSS來驅動,GSS保證幀數的穩定,即使出現網路延遲,也必須在確保收到該幀的所有輸入後才執行該幀的處理。

實現方案上,大致可以分出3種,分別是無主機結構、有主機結構、伺服器主機結構

u  無主機結構

2的拓撲結構中,所有GSS功能對等,該方案需要進行特殊的對幀處理,確保所有客戶端都已經同步並且收到所有的輸入。但是,由於網路上的各個客戶端完全對等,一旦某個使用者網路狀況出現延遲或者中斷等異常,將影響其他使用者的操作體驗,所以該方案簡單公平但體驗容易受限

u  有主機結構

6,在各個客戶端中隨機選擇一個的GSS作為主機,同時負責對幀控制及輸入輸出管理,其他GSS僅跟GSS主機通訊,GSS之間互相不通訊。該方案的好處是,遊戲的體驗只受主機與本機的網路與本機器狀況的影響,其他GSS出現的任何故障都不會影響其他人,當GSS主機完全失去聯絡時,其他GSS也可以重新仲裁得出新的GSS主機來,但該結構主機在客戶端,容易給外掛有可乘之機,對輸入對幀等能進行特殊處理,最終導致遊戲喪失公平性。此方案能保證玩家體驗,但安全性較低

u  伺服器主機結構

伺服器主機結構,是將6的結構中的GSS主機的的對幀控制及輸入輸出管理功能放在伺服器上,降低GSS客戶端的客觀影響,保證了大部分玩家的體驗,且其中有玩家作弊,也能馬上檢測到,保證遊戲的公平性,但結構上已脫離p2p設計,通訊流量隨使用者增加,負額指數級增長。該方案安全性高,保證玩家體驗,但對服務負載有一定的要求。

u  其他

融合有/無主機與伺服器主機的結構。伺服器主機結構的特點在於控制權在服務端,在有狀態的網路遊戲中,可以有效防止遊戲資料修改、遊戲加速等外掛,在服務端硬體資源方面,可以增加有/無主機結構減輕負擔,大部分功能用有/無主機結構處理,關鍵操作由伺服器主機結構處理等,讓GSS主機與伺服器主機協同服務

三、        伺服器主機結構設計

伺服器主機結構的特點如上所述,這裡再深入展開對該結構的分析與設計。

         伺服器設計

圖7

伺服器主要是起到控制作用,進行客戶端的對幀控制和輸入輸出管理。如7,伺服器每幀都發驅動幀驅動客戶端執行幀處理,當客戶端有輸入被伺服器接收到,則伺服器當前幀內將輸入同步輸出給各個客戶端.

網路上由於客戶端的狀況多種多樣,客戶端幀數可能跟不上伺服器,如8所示,如果客戶端出現掉幀情況,則在收到驅動幀後需要加速執行,以追上其他客戶端的速度,避免掉幀的使用者一直在對過去的事件進行響應。

遊戲應該優先保證正常使用者的體驗,所以當有玩家出現卡幀情況的時候,不應選擇暫停其他玩家,而是讓他慢慢的追趕上來,設計上,伺服器即可以採用客戶端的正常速度,按幀驅動客戶端,但當網路都出現突發狀況的時候,如9,通訊異常時,2個客戶端都對幀數2缺失,如果伺服器照常執行,到恢復網路狀況時,會出現情況是,每個客戶端都卡了幾幀之後,加速拉了幾幀。所以,針對這種情況,增加客戶端的對幀操作,即客戶端執行第1幀時,跟伺服器說可以播放第二幀了,然後伺服器開始驅動第二幀動作,考慮網路延遲情況,可以提前對幀第n幀的,效果如9,左邊客戶端第二個對幀操作使伺服器開始推動第二幀進行,而右邊客戶端的第二個對幀動作其實不起任何作用

圖8

圖9

客戶端設計

客戶端設計由兩部分組成,分別是GSS模組和渲染模組。

GSS模組包含物品系統、角色系統、AI系統、場景系統還有其他相關係統等,同時,輸入輸出和幀數控制也一起整合在GSS模組中。GSS中各系統功能分別是:

         物品系統:       遊戲物品以及物品的效果

         角色系統:       角色包括玩家角色、npc及apc等

         ai系統:          驅動apc行動的控制模組

         場景系統:     場景物件、地圖、尋路等

         其他系統:      其他類似技能、狀態等系統

         輸入輸出模組:       監聽玩家輸入,將玩家輸入上報伺服器,同時監聽伺服器輸入,綁定當前幀輸出

         幀數控制模組:      監聽伺服器驅動幀,驅動執行每幀處理

GSS模組中各個系統的執行,由幀數驅動,不引入其他時間線。有如物品持續時間、狀態持續時間等都以幀數作為唯一的時間軸。幀與幀之間的播放頻率,則由伺服器統一控制,但由於網路抖動等影響,幀的頻率並不是太穩定,為避免播放抖動,幀數控制器需要進行一定的平滑處理。

客戶端的渲染層,由GSS模組驅動,為減少模組間的耦合,GSS模組使用事件通知機制驅動渲染層表現。具體細分事件型別如12(具體專案具體事件拆解)

由於渲染層與GSS只做到事務級的同步,而GSS與渲染層的播放速率有可能不同,則為保證較好的表現效果,GSS的邏輯幀需要與渲染層的渲染幀做固定比率的繫結,譬如13的1:2,當GSS邏輯幀數不變的情況下,渲染幀掉幀時,能經過換算得到當前邏輯幀對應的渲染幀數,出現GSS幀數暫停時,則邏輯幀也跟著一起暫停

其中  OnUpdate由引擎在每幀呼叫,GetNewestFrame獲得邏輯幀通知過來的最新幀,這樣,保證了邏輯幀中關鍵幀進行傷害計算時,渲染幀不會脫幀嚴重。

四、        反外掛與斷線重連