發表文章

目前顯示的是 7月, 2020的文章

在多人遊戲環境變更角色移動速度 (一)

圖片
簡介 在還沒有任何網路延遲處理的經驗下,很容易做出遇到延遲就會產生問題的功能。 例如說做一個緩速功能,只要遇到網路發生延遲,玩家就會感受到拉回。 在過去的專案有幸遇到前輩指教,在UE4做了一點驗證,本篇算是學習的成果。 本系列我將會以一個實際的UE4 4.23案例做說明。 要實作的功能是: 玩家按下某一個鍵後,會進入移動射擊狀態(假設名字定義為Strafe),放開按鍵後離開移動射擊狀態(UnStrafe)。Strafe時,移動速度會減慢一半,UnStrafe後移動速度回到正常。 然後以新手的角度實作,接著提到如何模擬網路延遲,驗證新手的實作方法有問題,以及問題在哪邊。 再來就是提出正確的解法。這個解法需要以C++繼承UE4內建的CharacterMovementComponent,並複寫部分函式。這樣的做法伺服器端就會接受玩家的指令,如同玩家送出的移動一樣,不會造成拉回。 本系列目標是能夠介紹一系列的流程,包含如何開發移動減速功能,如何驗證網路延遲,結束於改善網路延遲移動的問題。 讀者可能需要知道什麼是RPC,文章前面提的部份是BP專案就能做到。後面要改善移動的時候才需要C++專案,有需求的人可以參考部份就好。 本篇不會提到改善網路延遲移動的做法,該作法會放到下一篇。 新手做法(以RPC) 本節會介紹我當初在錯誤的觀念做出來的做法以及結果。雖然可能有人會想說為什麼要介紹錯誤的觀念?主要是我認為並非所有人有網路基礎。所以有必要先用比較淺顯易懂的方式介紹這個需求的功能,把基礎建設先解釋完。然後接下來我只要專注在介紹修正錯誤的部份,避免本篇文章的閱讀難度一開始就過高。 首先在玩家的PlayerCharacter要新增按鈕接收的事件,在這邊我用input action strafe定義了輸入事件strafe,觸發的話就進入strafe,放開事件就離開strafe。 在多人連線的架構,直覺的作法就是client收到按鍵事件後,玩家角色端先套用Strafe處理,然後透過reliable RPC發送事件給server。server收到事件後作一樣的處理。 所以我們要新增兩個事件,一個是PerformStrafe 根據現在事件是Strafe還是UnStrafe,作移動速度的變更,如圖所示。 另一個則是Client,通知Server的reliable RPC 事件,命名為Server

Build Static Navigation Mesh with Commandlet in World Composition

圖片
簡介 先前有提到因為地圖被細切成很多張的關係,想要使用static nav mesh有幾個困難處要解決: 1. 地圖範圍很大的時候,是沒辦法一次載入所有地圖,只按一次build path就完成的。 不僅會執行很久,也會遇到build path失敗的情況。失敗會有警告訊息並且有部分nav mesh不完整。 2. 如果想要每張地圖各別計算,要在編輯器內重複的讀取子地圖,build path,子地圖存檔,卸載子地圖。 這樣的流程其實更適合用自動化來做。 這是本系列的最後一篇 目前一共有以下幾篇為系列的文章 1. Import RealWorld Landscape to UE4 https://yekdniwue.blogspot.com/2020/06/import-realworld-landscape-toue4.html 2. 了解Landscape的組成元件 https://yekdniwue.blogspot.com/2020/07/landscape.html 3. Generate Navigation Mesh with World Composition https://yekdniwue.blogspot.com/2020/07/GenNavMesh1.html 4. Build Static Navigation Mesh in World Composition https://yekdniwue.blogspot.com/2020/07/AutoBuildNavMesh.html 名詞與縮寫說明 在開始之前,先介紹一些本篇文章會用到的名詞或是縮寫。 NBV: Navigation Bounds Volume,用來定義navigation mesh的範圍。 P-Level: Persistent Level。在本篇指的是在World Composition模式下的主地圖。 Sublevel: 在本篇指的是在World Composition模式下的各個子地圖,可能是透過tiled height map匯入進來的。 前置準備 要能夠執行期間讀取/卸載存在子地圖的靜態nav mesh資料,需要以下步驟。 我試過很多方法,下面的步驟缺一不可。這些步驟都是在開啟P-Level的模式下運作。 1. 放置一個NBV在P-Level中,可以不需要跟任何東西交集

Generate Navigation Mesh with World Composition

圖片
簡介 使用先前提供的做法,把現實世界的地形檔匯入UE4之後, 畫面表現正常了,地圖也會根據設定的streaming distance運作。 下一個目標就是讓AI角色能在這塊地形正常的跨區域移動。 但是我很快就遇到兩個問題 1. 在play in editor遇到新的地圖載入的時候卡頓。 2. Navigation mesh要build 超久 首先是我在play in editor內,只要遇到地圖檔讀取就會造成卡頓, 但是我的地圖檔除了地形跟navigation mesh之外沒有放置其他的物件。 再來就是在build navigation mesh的時候超級慢,Build一張要5分鐘以上。 並且會伴隨很多的warning。 我做了不少的實驗想要嘗試改善這些問題,但是最後都是失敗的。例如: 降低地形複雜度 一開始我有嘗試用Flatten tool把地形輾平,也沒有加快Build path的速度。 代表地形的複雜度不影響build path以及loading的速度(或是差異不夠大)。 維持分割地圖數,降低height map解析度 將每一張tiled height map解析度輸出的時候從2017*2017降為505*505, 沒有差很多,但是地形大小不一樣了,不符合我的實驗。 效能改善的基本重點,當然是希望輸入輸出儘可能一樣,改了就不對了。 維持總解析度幾乎一致,分割地圖數變多。 例如原來是一張大地圖檔輸出成4*4張tiled map(2017*2017)。 改為一張大地圖檔輸出成9*9張tiled map(505*505)。 可想而知,每一張地圖都變小了,應該可以有效增加解析度, 但是原來只要build 16個level的navigation mesh。 現在變成要build 81次... 手動操作一兩張地圖測試後,確定是可以降低讀取時間。 不過以人工來說過於費時。需要靠程式批次處理。 因為navigaion mesh存在各個子地圖會增加地圖檔大小,有可能讀取卡頓問題也跟資源變大有關。 最後發現UE4提供不少產生navigation mesh的用法,於是研究一下各種方法的優缺點,或許可以解決讀取問題。 這是本系列的第三篇 目前一共有以下幾篇為系列的文章 1. Import RealWorld Landscape to UE4 https://yekdniwue.blo

了解Landscape的組成元件

圖片
簡介 官方文件連結 https://docs.unrealengine.com/en-US/Engine/Landscape/TechnicalGuide/index.html#recommendedlandscapesizes 一開始接觸Landscape,對裡面的各個名詞以及擁有各式各樣的數目感到非常的陌生。 就算看文件還是有很多細節是不懂的 後來跟同事一起研究,想到一些測試方法,我後續測出一些結果與結論,在本篇說明一下。 這是本系列的第二篇 目前一共有以下幾篇為系列的文章 1. Import RealWorld Landscape to UE4 https://yekdniwue.blogspot.com/2020/06/import-realworld-landscape-toue4.html 2. 了解Landscape的組成元件 https://yekdniwue.blogspot.com/2020/07/landscape.html 3. Generate Navigation Mesh with World Composition https://yekdniwue.blogspot.com/2020/07/GenNavMesh1.html 4. Build Static Navigation Mesh in World Composition https://yekdniwue.blogspot.com/2020/07/AutoBuildNavMesh.html 組成結構與了解 有關Landscape的組成結構,Level裡面可以放置Landscape,一個Landscape有一到多個components。 每一個component又可以決定要細切2*2個section或不細切兩種。一個Section又由多個Quads所組成。 最後一個Quad就是兩個三角片,為3D最基礎的繪製單位。 數量限制規範 一個Landscape的Component數目是有規範的,範圍是1~1024個,並且要是2的冪次方。 一個Component的Section數目如同前面所提,只有1*1與2*2兩種。 一個Section的Quad數目最少是7*7,最大到255*255。 不同參數下的Draw call 一個Component 2個draw calls,然後一個compon