ue4 无限地图_RPG游戏开发日志13:无限地图的实现
寫在前面
本項目同步上傳于coding上,國內讀者可以通過在coding下載項目。
也歡迎你加入我的UE4學習交流QQ群:872537977。如果你喜歡我寫的文章,也希望你點贊、收藏、轉發。謝謝!
如果你喜歡我寫的文章,也希望你點贊、收藏、轉發。謝謝!
如果你想參與到這個項目的開發中來,唯一的要求是像我一樣編寫開發日志讓更多的人看到并學習。
coding地址:https://git.dev.tencent.com/JeremyBrett/uRPG.git
上一期中,我們分享了之所以要制作體素地形游戲的心路歷程,以及這中間的一些思考。這一期我們就來開始著手實現。今天來完成第一步,制作一個可以無限生成的地形。
需求分析
無限生成的地形,實現的原理就是根據玩家操縱的角色所在的位置,動態的對周圍的chunk做增減。加載的過程就是把數據生成為對應的actor,而卸載的過程,就是反過來,將生成的actor 干掉的同時將數據緩存下來以便之后再生成。因此,游戲中的所有內容應該都是基于三維網格的(至少我目前是這么理解的)。
相關函數
我們將相關的代碼先寫在Bp_PlayerController中,這部分包括了四個函數,分別是Initialize、updatePosition、AddChunk和RemoveChunks,我們先介紹一下如何將這個四個函數添加在事件圖標中。很好理解。Initialize函數負責初始化變量,所以只需要在BeiginPlay時候調用一次。而其他三個函數需要無時無刻不進行調用。所以放在tick事件中每幀調用。
事件圖標
Initialize初始化
初始化函數,顧名思義就是對ChunkSize做一個初始化,這里是使用一個Chunk容納的Voxel數量和單個Voxel的尺寸的乘積得出的,而這兩個參數都是預先設置好的常量。而ChunkSizeHalf這個變量就是為了取Chunk的中心點方便而特意設置的,這個我們在后文中會介紹。
Initialize初始化
updatePosition更新位置
這里我們新建一個Vector類新的變量,命名為CharacterPosition。我們通過獲得當前控制的Pawn的位置來給這個變量賦值。處于安全考慮,在此之前我們通過IsValid驗證了一下Pawn是否非空。
然后我們來判斷一下當前所在的Chunk是哪一個,方法很簡單,我們通過將玩家位置的X坐標和Y坐標和ChunkSizeHalf相除,并分別和我們設置的變量ChunkX****ChunkY做對比,只要其中一個不相同,就證明Chunk變化了。
updatePosition前
如果Chunk更新了,那么我們重新設置ChunkX和ChunkY這兩個變量的值。并返回一個bool類型的返回值Ture,代表Chunk變化了。否則直接返回false。
updatePosition后
checkRadius檢查半徑
在介紹AddChunk函數前,先說一些這個宏,顧名思義,就是根據坐標判斷一下chunk是否在以玩家位置為圓心,以RenderRange為半徑的圓形范圍內。然后再進行下一步操作。
checkRadius
AddChunk添加Chunk
順著思路繼續往下完成,我們來添加Chunk。這里其實就是根據上文中提到的半徑變量RenderRange畫一個圓,這個圓形范圍內遍歷chunk,如果有chunk沒有被創建則創建。否則不用做什么操作。這里通過兩層ForLoop來遍歷X、Y坐標。
這里要說明的是ChunkCords這個變量,這是一個Vector2D的數組變量。這個變量記錄著當前已經創建的chunk的坐標。并通過查找數組中是否有對應坐標(通過CONTAINS節點)來決定是否需要創建。
AddChunk前
一旦需要創建Chunk,首先就是將坐標添加到ChunkCords中,其次就是通過SpawnActor節點創建chunk,我這里新建了一個命名為Test的Actor(很簡單,只有一個staticMesh,這里就不放出截圖了)。生成位置就是添加在chunkCords中的坐標(Z坐標為0)。
最后,我們新建一個Test數組類型的變量,并命名為Chunks。然后將這個新生成的Test添加其中,這一步的目的是為了方便之后的刪除操作。
AddChunk后
這一步結束后,我們可以運行游戲來測試一下了,對了,給我們玩家出生位置設置在一個合適的點。然后移動,確實隨著移動產生了更多新的Test。并且我們可以根據實際體驗來調整半徑RenderRange的大小。但是隨著Test的增多,性能必然下降,這顯然不符合我們的預期。所以我們要進行“回收”。
RemoveChunks移除Chunks
其實Remove操作就是Add操作的反向,依然是分為前后兩部分,前半部分進行條件判斷,后半部分對于符合條件的項執行操作。
首先我們遍歷ChunkCords中存放的所有坐標,然后通過CheckRadius來判斷是否在玩家范圍內。如果不在,那么對這個坐標點對應的Test執行操作。
RemoveChunks前
我們前文中創建的變量Chunks這時候起作用了,根據遍歷Index,將數組中對應位置的Test執行DestroyActor操作。并且將其從Chunks和ChunkCords這兩個數組中移除。至此所有的操作就都完成了。
RemoveChunks后
測試調優
測試,哦對了,千萬別忘了前文中講的,將這幾個函數放在對應的事件下執行。
運行游戲,test確實按照我們預期的添加和移除了。
但是奇怪的是,當我們移動時會有明顯感到阻尼的存在。并且當我們跳躍落地后會被再次彈起,我還沒有搞清楚這是什么原因,是不是碰撞填寫的不對造成的。這個問題我們留給之后解決把。
效果演示
下期預告
在下一期中,我們將Test替換成我們想要的真正意義上的Chunk,這部分需要用到ProceduralMesh組件,并且要使用C++來完成。
那我們下期再見吧!
總結
以上是生活随笔為你收集整理的ue4 无限地图_RPG游戏开发日志13:无限地图的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 西文是指什么_儒家君子文化:何为君子?为
- 下一篇: des vue 双倍长 解密_[转]单倍