用HBuilder做網(wǎng)站的模板關鍵詞優(yōu)化顧問
文章目錄
- 一、常規(guī)學習:
- Mirror核心功能有
- 服務器和主機
- 二、時間戳批處理
- 時間戳
- 三、TCP和UDP
- 四、CCU(同時在線人數(shù))
- 五、SyncDirection(同步方向)
- 六、RTT(往返時間)
- 七、Connection Quality(連接質(zhì)量)
- 八、Lag Compensation(滯后補償)
- 一、獨立算法類LagCompensation.cs
- 二、Log Compensator組件
- 九、Client Side Prediction(客戶端預測)
- 十、History Bounds(歷史邊界)
一、常規(guī)學習:
Mirror是一個用于Unity多人游戲的功能系統(tǒng)。它允許在其中一個參與者同時承擔服務器的功能,因此不需要專用的服務器進程從而減少了開發(fā)人員的工作量。
Mirror核心功能有
1.消息處理程序
2.通用高性能序列化
3.分布式對像管理
4.狀態(tài)同步
5.服務器與客戶端的各種鏈接等.
服務器和主機
1.服務器是游戲的一個實例,所有客戶端與其鏈接。由服務器對數(shù)據(jù)進行處理并回傳給各客戶端展示。
2.服務器可以是“專用服務器”
也可以是“主機服務器”。
“專用服務器”
僅作為服務器支行游戲?qū)嵗?br /> “主機服務器 “
當沒有專用服務器時,即充當服務器也充當客戶端。
下圖代表了三個玩家。在游戲充當了主機也就是本地客戶端,并且兩者在同一客戶端支行。另外兩個是遠程客戶端。
因為主機與本地服務器在同一進程中,因而可以使用“特殊”
的通訊方便直接調(diào)用方法和消息。
遠端客戶端則通過常規(guī)的網(wǎng)絡通訊與服務器交互,Mirror會自動處理這些工作。
多人游戲系統(tǒng)目標之一是使服務端、客戶端代碼相同。因而多數(shù)時候你只需要考慮一種類型的客戶端,Mirror將會自動處理差異。
二、時間戳批處理
你發(fā)送的每條消息將被批處理直至當前幀結(jié)束,以最大程度的減少傳輸?shù)南?。消息中將會把大量的小消息合并為一條進行發(fā)送。
客戶端和服務端都會進行批處理以最大化的減少性能消耗。
時間戳
確保遠程發(fā)送消息的時序性,接收到消息后對他們之間進行插值??梢詼蚀_的知道物在服務器上,何時處于何處。
早期版本通過NetworkTransform來實現(xiàn),成本巨大因為需要包含一個4字節(jié)(float),甚至8字節(jié)(double),當在大型游戲中時,寬帶壓力會迅速增加。
而NetworkTransform只是其中一種組件,其他的組件也可能需要時間戳,這將進一步增加寬帶消耗。
為了減輕寬帶壓力,Mirror每個批次都包含8個字節(jié),但并不是每條消息都包含,而是每1200個字節(jié)批出來一次,這有效減輕了寬帶壓力。
在客戶機上,所有對象數(shù)據(jù)都以消息/批處理的形式從服務器到達。因此,在任何給定的時間,您都可以發(fā)現(xiàn)對象的Rpc/OnDeserialize/OnMessage處理程序何時由服務器通過NetworkClient.connection.remoteTimeStamp發(fā)送。
在服務器上,只有玩家擁有的對像才能于家連接中獲得消息。因此,在任何時間,您都可以找到對像的Cmd/OnDeserialize/OnMessage處理程序,由客戶端能過connectionToClient.remoteTimeStam發(fā)送
三、TCP和UDP
TPC由1970年開發(fā),UDP由1980年引入,TCP內(nèi)靠性,時序性,但延遲較高,UDP反之。
四、CCU(同時在線人數(shù))
Mirror 可以處理多少個CCU,通常來說每個地圖可以處理200CCU,但理論上是可以達到1000個。
官方嘗試了一些項目480CCU時已有些卡頓,同時3D比2D的開銷會更大。
五、SyncDirection(同步方向)
Mirror新增了SyncDirection功能
Mirror 中通常從服務器同步到客戶端,但某些組件(如:NetworkTransform)需要在客戶權(quán)限的情況下同步到服務器,因為OnSerialize只會從服務器到客戶端,這里有幾個缺點:
1.同時進行OnSerialize和手動遠程調(diào)用需要大量的額外代碼
2.會有額外寬帶消耗,因每個命令包含一個函數(shù)哈希
3.間隔需要手動實現(xiàn),因為syncInterval僅適用于OnSerialize.
因此OnSerialize提供了從客戶端同步到服務器,組件提供了SyncDirection功能。
六、RTT(往返時間)
往返時間是指消息到另一端并返回的時間,由以下兩個因素決定:
1.延遲:網(wǎng)絡通過互聯(lián)網(wǎng)傳播需要時間
2.更新間隔:消息需要被處理并發(fā)送回另一端,與服務器處理時間及壓力有關。
用戶可以在NetworkTime.rtt查看,服務器可以在每個不同鏈接的NetworkServer.connection.rtt查看
如果你想在游戲中顯示rtt可以使用NetworkPingDisplay
七、Connection Quality(連接質(zhì)量)
Mirror的連接由三部分組成:
ConnectionQuality.cs提供了以下連接質(zhì)量級別:
Public enum ConnectionQuality : byte
{
EXCELLENT, //高水平理想體驗
GOOD, //非常適合所有人,高水平連接
FAIR, //非常明顯卡頓,讓人不愉悅
POOR, //無效的玩家
ESTIMATING, //仍在評估
}
兩種發(fā)起方式:
Simple(based on Ping & Jitter)
Pragmatic( 基于快照插值)
NetworkPingDisplay
此組件可以添加到NetworkManager中,以在屏幕右下角顯示ping和連接質(zhì)量指示
NetworkManager回調(diào)
以覆蓋CalculateConnectionQuality方式注入??梢栽贜etworkManager中配置。
OnConnectionQualityChanged可用于向用戶顯示警告,默認情況 下會發(fā)出一條日志。
八、Lag Compensation(滯后補償)
快節(jié)奏的第一人稱射擊需要延遲補償,又叫回滾。而對于MMORPG、紙牌、回合、等策略則不需要。
為什么需要回滾,假設在設計游戲中你和另一名玩家同步需要50毫秒,到達服務器需要50毫秒。這里就有100毫秒的時間差。這100毫秒里可能對方發(fā)生了位移,可能使你的設計位置不準確。
滯后補償分為兩部分:
一、獨立算法類LagCompensation.cs
該算法可以記錄采樣類型任何記錄。
換句話說,如果你愿意,您可以根據(jù)自己的需要定制它,這是底層代碼,使用高級組件會更方便。
二、Log Compensator組件
只需要添加下面組件,Mirror將會管理指定Collider的歷史快照。
當你做為玩家在本地發(fā)射子彈時,[Command]將輸入發(fā)送到服務器,這進我們不檢查另一端玩家是否補擊中,
而是檢查另一端玩家當時的Lag Compensation(滯后補償)
官方文檔中提供了例子。
九、Client Side Prediction(客戶端預測)
打開Examples/Billiards例子,選擇NetworkManager -> LatencySimulation 增加一些延遲(50ms),構(gòu)建選擇Server Only.
這是一個桌球游戲,在你擊打白球時,由于數(shù)據(jù)需要發(fā)送給服務器再回傳我們能明顯的感覺到打擊感滯后。
因此我們需要要用客戶端模擬預測結(jié)果,一旦服務端返回狀態(tài)我們必須立馬糾正它。
由于大多數(shù)物理引擎,如Unity的PhysX是不確定的。這以為著在客戶端和服務端施加的力(浮點數(shù))會有所不同,而差異會逐漸累計。
為什么不使用確定性物理引擎:
一、Unity沒有
二、工作量大
三、比常規(guī)物理引擎慢
最簡單回滾流程說明:
由客戶端執(zhí)行Rigidbody.AddForce() 同時發(fā)送給服務器端執(zhí)行[Command]CmdApplyForce(force)
服務器執(zhí)行wellRigidbody.AddForce(force)
服務器同步新的剛體位置到客戶端,但些修正將有一定時間差,而客戶端一直在進行修改。
這也以為著客戶端將一直有明顯的“后跳”行為。
應當如何解決因時間差帶來的后跳問題呢?
由客戶端執(zhí)行Rigidbody.AddForce() 客戶端保存剛體位置 每50ms保存一次,以便后面進去比較
發(fā)送給服務器端執(zhí)行[Command]CmdApplyForce(force)
拿到服務端的位置后與100ms(50+50來回)前的位置進行對比矯正
這部分內(nèi)容可以了解一下而已,事實上Mirror已經(jīng)為我們處理完這部分內(nèi)容
在客戶端中使用:Predicted Rigidbody(預測剛體)插件,情況將會簡單很多。
預測和修正總是很難應用在剛體上。為了固話效果組件提供了兩種模式:
Smooth(平滑):一般開始移動,所有的物理組件(Rigidbody+Colliders)都會移動到一個不可見的Ghost對象里。
渲染器在原位置并平滑插值到Ghost對像的位置,這將提供非常平滑的結(jié)果,但創(chuàng)造和跟隨會有更大的額外成本開銷。
Fast(快速):物體保留在原來的位置上,渲染器直接移動到結(jié)果所在位置,這種方式更節(jié)約性能。
關于預測的類型可以在forecast .cs中找到它。
Mirror還可以用于其他類型的預測,但還需要了解后自行補全部分邏輯。
關于Mirror對于大型場景的預測
傳統(tǒng)上預測算法并回滾模擬整個場景我們需要Physics.Simulate()
此方法可以最正確的模擬出結(jié)果,但性能消耗巨大,不適合用于大型場景。
Mirror經(jīng)過努力兼容了大型場景的物理同及堆疊物理的同步。
十、History Bounds(歷史邊界)
優(yōu)化延遲補償和客戶端預測,為了最小化性能開銷,在我們使用的對像先對其強制使用HistoryBounds
使用方式:
將HistoryCollider添加到NetworkIdentity上
確保NetworkIdentity中有碰撞器,并拖至actualCollider中
按下播放鍵,啟動Gizmos,注意橙色的HistoryCollider.
組件以橙色包圍盒顯示,這以為著您可以使用物理攝像進行物理檢測。
當玩家開槍時,對所有的HistoryColliders進行射線檢測,反出我們需要檢測的玩家。
然后對碰撞器的父級NetworkIdentity使用延遲補償處理,然后再檢查他是否補擊中。