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