GameDesign 板


LINE

網頁版 https://yekdniwue.blogspot.com/2020/08/CustomMove2.html 簡介 在前一篇我已經介紹一個完整的範例, 說明如何製作一個支援網路的功能, 如何做測試, 跟如何驗證這個做好的功能, 在網路延遲的環境是否能正常運作。 前一個做法確定是不行的,玩家會感到畫面不流暢。 因此本篇要介紹如何正確地修改移動相關的功能, 讓Server端能夠信任Client發送的指令, 避免Server頻繁的矯正Client的位置。 這篇其實會比較偏向程式碼實作,敘述會少很多。 簡單來說就是看code比較快啦。 當初是從CharacterMovementComponent的Crouch挖出來的。 所以如果想要自己試試看的話,可以去挖出引擎有關Crouch的程式來看。 跟之前一樣,裡面的程式碼都是我經過精簡過了, 多餘的實作項目我盡可能的都沒列在裡面, 所以最好還是按照順序看完,以免出錯。 再繼續往下看之前,請確認以下的詞你都知道是什麼意思: 1. Replicated Property 2. ROLE Authority 3. ROLE Simulated Proxy 4. ROLE AutonomousProxy 礙於篇幅的關係,這邊不會多做介紹。如果有不熟悉的項目,請先前往 https://docs.unrealengine.com/en-US/Gameplay/Networking/Actors/Roles/index.html 惡補一下。 為角色新增移動模式 要製作這種由玩家的操作改變移動速度的作法, 其實要用到的是MovementMode的切換。 也就是製作一個新的MovementModeStrafe, 然後玩家按鍵的時候進到這個MovementMode, 放開的時候回到預設的MovementMode。 為了達到這個目的,我們總共需要新增 兩個C++ class,以及一個BP class, 所以就是5個檔案。 1. CustomCharacter 2. CustomMoveComponent 3. BP_CustomCharacter 而移動速度的改變,核心做法是override GetMaxSpeed(), 如果角色正在Strafe狀態,MaxSpeed就回傳 Super::GetMaxSpeed()*StrafeSpeedRatio CustomCharacter實作 大致上要實作的項目 CustomCharacter要能接受玩家的輸入,所以跟之前的作法一樣, 要開出Strafe以及UnStrafe兩個函式給外部使用。 為了得知Strafe/UnStrafe的狀態變化時機,所以我也開出了四個函式: 1. OnStartStrafe 2. OnEndStrafe 3. BP_OnStartStrafe 4. BP_OnEndStrafe 分別是C++以及BP的事件,提供給Gameplay需要的時候使用。 Server需要將Movement的狀態同步給SimulatedProxy, 所以要新增一個變數bIsStrafed, 用來讓SimulatedProxy獲得事件通知。 也因為要Replicate變數bIsStrafed, 就要實作GetLifetimeReplicatedProps函式。 因為我們會以CustomMoveComponent取代 原生的CharacterMovementComponent, 我會建立一個指標指向CustomMoveComponent。 然後在Constructor的時候做替換。 替換MoveComponent以及同步變數 在Constructer替換MoveComponent, 然後在GetLifetimeReplicatedProps同步變數bIsStrafed, 並且只同步給Simulated Proxy。 因為Autonumous Proxy在輸入的當下就切換狀態了。 Strafe與UnStrafe實作 在CustomCharacter內,Strafe跟UnStrafe只是負責 將指令帶給CustomMoveComponent, 後續就交給CustomMoveComponent在傳遞資訊的時候做處理。 變數同步與事件通知 收到變數bIsStrafed改變的通知時, 我們就是呼叫CharMovement對應的函式做處理。 而收到OnStartStrafe與OnEndStrafe時,就是呼叫BP版本的對應函式。 可能會有人有疑惑說為什麼一個事件要分C++跟BP兩個函式, 而不是直接使用BlueprintNativeEvent直接一個函式定義起來。 主要是因為如果使用NativeEvent,那BP端是可以不呼叫C++實作的。 這個做法可以確保C++的部分一定會被執行到,不會被跳過。 到這邊CustomCharacter的實作就結束了。 CustomMoveComponent實作 大致上要實作的項目 CustomCharacter的實作其實還是比較偏Gameplay層, 就是開出函式,建立事件通知。 CustomMoveComponent要實作的項目才是核心的部份, 裡面的程式碼比較少見(其他系統不會看到這些類別與函式)。 CustomMoveComponent的實作根據不同的ROLE,有不同的實作部份 1. Autonomuous Proxy handling 2. Authority handling Autonomuous Proxy要把bWantsToStrafe的資訊塞進FCustomSavedMove中, 這樣client給Server的每個移動資訊都會帶有這個移動是否是Strafe的資訊。 Authority從FCustomSavedMove內抽出bWantsToStrafe的資訊後, 就會以正確的速度計算移動,需要減速移動就會減速移動。 因為移動跟速度變化綁定在同一包, 所以Server不會認為Client的移動有異常,就不會做位置矯正。 一些基本雜項設定 設定PawnOwner: 有兩個地方要設定PawnOwner。SetUpdatedComponent以及PostLoad。 Strafe與UnStrafe: 如果是Server(Authority)的話,直接變更bIsStrafed, 這樣SimulatedProxy會在OnRep_IsStrafed收到通知並處理。 而到底移動速度的更改怎麼實作,就是透過檢查現在是否是Strafe, 然後override GetMaxSpeed函式,如果Strafe中就乘上減速比例。 移動資訊傳遞 剩下的部份就是處理移動資訊的傳遞, 總共還有以下幾個函式在CustomMoveComponent要實作: 1. UpdateCharacterStateBeforeMovement 2. UpdateFromCompressedFlags 3. GetPredictionData_Client 修改Client送給Server的移動結構 要把Strafe的狀態告訴Server,就是要將Strafe的狀態塞進移動資料。 在FSavedMove的CompressedFlags提供了四個custom的bit可供我們使用, 也就是說我們被允許最多建立出16種移動狀態。 在這邊我會借用FLAG_Custom_0的0代表UnStrafe,1代表Starfe。 為了修改FSavedMove,我們要實作自己的版本: class FCustomSavedMove : public FSavedMove_Character 而SavedMove是被裝在FNetworkPredictionData_Client_Character裡面。 所以我們要實作自己的版本: class FNetworkPredictionData_Client_Custom : public FNetworkPredictionData_Client_Character 然後實作函式AllocateNewMove,裡面回傳我們自定義的FCustomSavedMove。 最後就是在CustomMoveComponent裡面實作GetPredictionData_Client。 在GetPredictionData_Client裡面我們要回傳自定義的class FNetworkPredictionData_Client_Custom。 這樣就能以我們自定義的移動結構取代原來的移動結構了。 將Strafe狀態整合進移動資料 可分為輸入輸出兩種情況, 輸入:Client把Strafe狀態塞進移動資料傳給Server。 輸出:Server從移動資料獲得Client送來的Strafe狀態。 輸入實作: Client(Autonumous)傳送移動資料給Server的處理流程: CharacterMovementComponent::TickComponent() ReplicateMoveToServer SetMoveFor CanCombineWith PerformMovement UpdateCharacterStateBeforeMovement CallServerMove GetCompressedFlags SetMoveFor: 從CustomMoveComponent複製bWantsToStrafe到FCustomSavedMove。 CanCombineWith: 如果bWantsToStrafe有變動,那兩個SavedMove要避免合併, 以免Strafe狀態的資料因為合併而遺失。 UpdateCharacterStateBeforeMovement: 在套用移動前再次檢查狀態是否有變化。 GetCompressedFlags: 將bWantsToStrafe存入CompressedFlags的FLAG_Custom_0。 輸出實作: Server(Authority)收到玩家資料的處理流程: ServerMove_Implementation MoveAutonomous UpdateFromCompressedFlags PerformMovement UpdateCharacterStateBeforeMovement UpdateFromCompressedFlags: 從SavedMove的FLAG_Custom_0取得Strafe狀態,存入CustomMoveComponent。 UpdateCharacterStateBeforeMovement: 在套用移動前再次檢查狀態是否有變化。 Server端Strafe狀態的變化事件會在這裡觸發。 程式碼在哪? 說了這麼多,你一定想問"到底要不要附程式碼" 你可以參考我當初找到的範例 [連結] 或是參考UnrealEngine的原始碼有關bWantsToCrouch相關的部份。 或是參考我實作的版本,已做成Plugin,但是BP角色的串接就要自己實作了。 [連結] 最後一哩路 按照以上作法實作,BP的character改為繼承CustomCharacter之後, 只要在使用者輸入的時候呼叫Strafe/UnStrafe,就完成了。 其他的事情都已經在C++處理完畢。如圖所示。 [圖] 實作完畢後你可以用前一篇提的方法做測試, 會發現就算lag設為500ms也不會有異常。 可參考影片: [影片] 結論 本系列所提的方法是為了解決如果玩家操作可以改變移動速度, 如果沒有把狀態變化跟移動資料一起傳給Server, Server與Client就會計算出不同的位置, 然後Client就會收到Server傳來的位置矯正, 造成玩家感受不良的問題。 然而一般常見的玩家對玩家,例如緩速技能,凍結技能, 這種牽扯的對象不是只有玩家對Server, 就沒有辦法使用這種方式處理。 要解決這種問題的困難度也高很多。 目前沒有繼續往後研究下去,所以這個系列應該會到此結束。 哪一天真的有實作出來並且經過驗證再分享吧(應該不會有機會)。 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 59.120.146.90 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/GameDesign/M.1596596646.A.EE7.html
1F:推 coolrobin: 未看先推 08/05 21:24
2F:推 sampp1213205: 有沒有考慮做教學影片放YouTube 08/05 21:49
3F:推 coolrobin: y大的內容比較偏引擎、技術研究 不太適合錄成影片吧 08/05 23:25
4F:→ yekdniw: 有很多原因 主因是製作影片需要時間太長 08/06 10:01
5F:→ yekdniw: 所以暫時沒有考慮 謝謝~ 08/06 10:01







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Soft_Job站內搜尋

TOP