虛幻4初級 簡單的仿絕地求生背包系統(網絡,UMG,藍圖接口)

Demo下載

先拋開UI部分暫且不論,需要什么:
  • 在世界中存在的能夠被拾取的Actor
  • 角色能夠知道附近有哪些Actor能夠被拾取
  • 存儲已拾取的,裝進背包的Actor
  • 能夠將背包中的的Actor扔出去
  1. 使用Interface標記Actor將能實現最靈活的配置,
    新建一個藍圖接口命名為PickupInterface。



    添加兩個函數分別是【Pickup】【Discard】
    Pickup函數輸入值新建一個PlayerController,輸出則為一個布爾值,判斷是否成功拾取


    Pickup函數

    Discard則只需要一個為布爾變量的輸出值,作用也是判斷是否成功丟掉
    Discard
  2. 在角色藍圖中創建一個碰撞組件用于檢測實現了PickupInterface接口的Actor
    我這里使用的是Box碰撞體。


    Collision

    將它的碰撞預設改為OverlapAllDynamic,并添加兩個事件


    CheckPickupCollision

    在角色藍圖中新建一個Actor數組變量,這個值不需要同步,用于存儲附近的實現了PickupInterface接口的Actor。
    添加兩個自定義事件,檢測傳入的Actor值是否實現了PickupInterface接口。
    Nearby

    在BoxCollision的Begin Overlap和End Overlap事件中分別使用:


    BoxCollision
  3. 已拾取的Actor,背包中的Actor存儲使用PlayerState來實現。


    PlayerState

    創建一個Actor數組并將復制模式設為Replicated,復制條件設為OwnerOnly(只在服務器和所屬客戶端復制,可有有效減少網絡傳輸量,缺點也很明顯,其他客戶端沒有更新)
    實現添加Pickup和移除Pickup的函數:



    前綴帶[Server]字樣的函數是RPC函數,他們的復制屬性為在服務器上運行并設為可靠函數(網絡的傳輸非常多樣化,可靠傳輸意味著一定會執行,但相較于不可靠函數,會損失一定的時間性能)
    RPC函數

    代碼層的框架已經ok了。

分析絕地求生的UI

圖片源自網絡

我們能夠顯而易見的分成三部分(背包與附近裝備列表[左],角色的實時顯示[中],武器裝備[右])
這篇教程就先實現左邊的。
我們再把左邊給拆開分析



綠框中的是顯示背包容積的進度條[Progress Bar]
紅框中的是兩個能夠滑動的控件[Scroll Box]
我們可以把紅框中顯示裝備列表給封裝起來,封裝的目的是可復用性,其使用方法就跟我們使用普通的小控件如滑動條,還可以在游戲中動態的創建控件。
列表中都是由一個個這個封裝起來的


item

而item又分為三部分,分別是左邊的圖片,中間的名字,右邊的數量,如果為不可以合并的裝備則會隱藏掉。

最小控件Item的制作 [ActionItem]

item

由上圖分析出控件的排列為左右結構,我們可以使用[Horizontal Box] (Panel Widget:不會渲染出來,用于對 Child Widget 進行布局)。左右空間還有不同的不透明度,使用[Border]。具體的文字圖片為[Text][Image]
關于細節:

  • 窗口尺寸變成長條形,其目的僅僅是方便顯示我們能夠直觀看出效果
  • 中間用于顯示名字的控件將使用填充作為父控件的計算方式
  • 啟用[Text]AutoWrapText自動換行,垂直居中
  • 子控件的Padding默認為(4,2),如有必要請歸零
  • 打開子控件的Is Varible


    外觀

    層次結構

    每個控件的具體參數下載示例查看。
    觀察上圖,我們需要幾個參數:

  • Image 顯示的圖標
  • Name 子項的名字
    創建一個結構體方便傳遞和使用


    ActionItemInfo

    參數

    回到PickupInterface添加一個函數【GetActionInfo】



    在ActionItem中添加PickupActor的引用并在生成時顯示:
    ActionItem

    在其構造事件中:
    ActionItem

拖拽

在ActionItem中實現拖拽的檢測和創建拖拽時使用的對象
需要覆寫如下2個函數分別實現檢測和創建【OnMouseButtonDown】【OnDragDetected】


覆寫函數

OnMouseButtonDown檢測是否有拖拽事件

檢測到拖拽事件后如何處理,這里是直接把自己傳進去

列表的創建

由于我們需要在列表中覆寫OnDrop事件,但是[附近的]與[背包中的]它們的OnDrop處理事件是不同的,所以我要分開來寫。

InventoryList
層次結構,其中ScrollBox的子項是需要動態創建的,我在這兒拖進去只是演示效果

效果預覽

藍圖方面創建一個更新列表的函數,也只需要這一個函數,因為列表的管理不是由Widget進行管理的,Widget僅僅是起到一個通知(給玩家)的作用:



InventoryList與NearbyList都是有如上部分的,唯一的不同就是OnDrop的處理,在InventoryList是添加進庫存,而在NearbyList中是移除:

我們先在MyCharacter中添加如下兩個函數:


MyCharacter

回到InventoryList,覆寫OnDrap:
InventoryList

之后復制一份InventoryList重命名為【NearbyList】,修改OnDrap:
NearbyList

MainInventoryWidget的制作:

層次結構

效果

封裝接口,簡化調用

在MyCharacter中顯示背包

對背包的Widget進行賦值

背包的顯示與關閉

UI更新的通知

并在MyPlayerState中使用通知接口:


MtCharacter

MyPlayerState中使用宏,宏的定義如下

通知更新的宏

使用示例

創建一個Actor,重命名為PickupActor,啟用復制和復制移動屬性,并添加一個StaticMesh (把mesh隨便設置一個,我設置的是cube),



打開類設置并實現接口PickupInterface


image.png

創建一個自定義事件,并設置復制為多路傳送,啟用可靠函數:

實現接口的函數:


接口函數




接下來你就可以拖進場景使用了,
還有很多細節未修復,比如釋放actor值的位置,應該是放在地板上。等等
也有很多的功能尚未實現(比如網絡延遲情況下的處理,類似于子彈多個數據的打包),我會在接下來的教程一一完善

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網絡請求組件 FMDB本地數據庫組件 SD...
    陽明AGI閱讀 16,003評論 3 119
  • (一) 是的 我又夢見你了。 醒來后夢里的情節多半都忘了 唯一清晰的就只有久違的你的臉——當時怎么就沒覺著你這么好...
    李霖不語閱讀 621評論 0 0
  • 讀書的好處那是不必多言了,但是你有沒有這么一種感覺:我明明有在讀書,卻沒什么收獲呀。這時你不防反思一下自己有沒有讀...
    每天慌閱讀 230評論 2 1
  • 好多人也不滿足,也想成長,但他們堅持不下去。遇到痛苦、困難、否定和打擊時,就開始懷疑自己,漸漸變得懶惰、放縱,最后...
    陽焱焱閱讀 603評論 0 1