<style></style>
原文:Unreal Engine 4 UI Tutorial
作者:Tommy Tran
譯者:Shuchang Liu
在本篇教程,你將學會如何創建,展示和更新一個HUD界面,
在游戲中,開發者使用影像和文字來展示玩家血條,得分等相關資訊,這就是用戶界面(UI),
你可以在Unreal Engine 4里利用Unreal Motion Graphics(UMG),UMG允許你通過拖拽按鈕,文本等UI元素來構建UI界面,
在本篇教程,你將學會:
- 創建展示得分和時間的HUD
- 展示HUD
- 當變數值變化時,更新得分和時間顯示
請注意,本篇教程涉及藍圖內容,如果你需要復習有關內容,請查看藍圖教程,
注意:本篇教程只是Unreal Engine 4系列教程的其中一篇:
- Part 1:入門
- Part 2:藍圖
- Part 3:材質
- Part 4:UI
- Part 5:制作簡單游戲
- Part 6:影片
- Part 7:音頻
- Part 8:粒子系統
- Part 9:AI
- Part 10:制作簡單FPS游戲
起步入門
下載示例專案并解壓,進入專案檔案夾,雙擊BananaCollector.uproject打開專案,
注意:如果你看到了專案是由較早的引擎版本創建的提示,這很正常(因為引擎經常更新版本),你可以選擇以拷貝副本的形式打開,也可以直接轉換專案版本打開,
點擊Play開始游戲,控制白色方塊接住掉落的圖形,你可以通過移動滑鼠平移方塊,10秒后,圖形會停止掉落,

我們要做的第一件事就是創建HUD展示兩個資訊:
- 玩家收集了多少個圖形的計數
- 距離圖形停止掉落的倒計時
其中需要使用到Widgets(控制元件),
關于控制元件
控制元件是一種提供簡單功能的UI元素,比如,按鈕控制元件提供了玩家可見可點擊的物體,

控制元件本身不一定是可視的,比如,網格面板掛件只是用于平均排布子元素,玩家看不見控制元件本身,但能看到控制元件的效果,

控制元件也可以嵌套控制元件,比如下面是一個自定義控制元件,它又包含了一個文本控制元件(名字文本)和文本輸入框控制元件:

你甚至可以創建一個鋪滿螢屏的控制元件,比如下面的控制元件作為一個標題界面鋪滿了螢屏,這個控制元件所包含了其他UI元素也都為控制元件,

了解完什么是控制元件,現在動手創建一個,
創建控制元件
Content Browser界面進入UI檔案夾,點擊Add New按鈕,選擇創建User Interface\Widget Blueprint,將其重名為WBP_HUD,

雙擊WBP_HUD打開UMG UI Designer,
UMG UI Designer
UMG UI Designer由七個主要元素組成:

- Designer:這個區域展示所選控制元件的外觀,通過長按右鍵移動滑鼠拖動面板,滑動滾輪縮放面板,
- Details:展示所選控制元件的引數
- Palette:可用控制元件串列
- Hierarchy:當前所使用的控制元件串列
- Animations:控制元件能夠基于位置,大小等外觀引數制作影片效果,該面板展示控制元件的所有影片
- Timeline:當你選中影片時,該面板會展示對應的影片引數和關鍵幀
- Editor Mode:通過該按鈕可以切換編輯器的Designer和Graph模式,Graph模式的編輯器顯示類似于藍圖的Event Graph,
創建Text控制元件
Text控制元件非常適合展示像計數和倒計時這樣的數字資訊,
在Palette面板搜索Text控制元件,通過按住左鍵拖拽控制元件至Designer面板,

別在意文本內容,等等我們會替換它,
先選中Text控制元件,在Details面板頂部的文本框輸入CounterText進行重命名,

你可以在Designer面板通過長按左鍵拖拽控制元件,

你也可以通過左鍵點擊拖拉選中框來調整控制元件的大小,這樣可以調整控制元件的包圍框,Unreal引擎不會渲染包圍框之外的內容,

同樣的,你可以通過Details面板輸入數值來修改控制元件的位置和大小,設定CounterText如下:
- Position X: 200
- Position Y: 50
- Size X: 500
- Size Y: 100

此時文本只占了包圍框很小一部分顯示,

我們可以在Detail面板的Appearance設定調大字體大小,在Font屬性的最右側文本框可以設定字體大小,

將字體大小調成68,

接著我們再在文本框旁添加一個圖示來提升視覺效果,
創建Image控制元件
Image控制元件可以讓我們展示像圖示一類的UI圖形,
創建Image控制元件并將其命名為CounterIcon,將Position X設成75,Position Y設成50,顯示在CounterText左邊,

接著在Details面板的Appearance設定顯示圖片,展開Brush設定,點擊Image欄位下拉框,選擇T_Counter,

由于控制元件與圖片的長寬不一樣,圖片看起來擠壓變形了,

除了手動調整控制元件大小,我們還可以使用Size To Content選項來調整控制元件大小,該選項會自動將控制元件大小調整成圖片大小,
點開Details面板的Slot(Canvas Panel Slot)部分設定,勾選Size To Content 選中框,

控制元件會適應調整成圖片的大小,

當游戲在不同螢屏尺寸下運行時,UI控制元件需要根據情況調整顯示位置,為了保持UI的布局,我們可以使用錨點,
錨點
錨點確定了控制元件位置的相對參考點,控制元件的錨點默認為其父物件的左上角,所以,當我們在給一個控制元件設位置時,其實是在設控制元件相對于錨點的位置,
下圖例子里,每個Image都以一個點作為它們的錨點(距離自身最近的角落點),

注意看每個Image是怎么與錨點保持相對位置的,合理利用錨點,就可以保證UI元素在不同螢屏尺寸上都保持統一布局,
我們也可以利用錨點來自動調整控制元件的大小,當錨點多于兩個點或更多時,控制元件會根據螢屏尺寸調整大小來保持它的相對尺寸,
下圖例子里,灰色長條的錨點為左上角和右上角,

在垂直方向上,灰色長條隨著錨點移動,但尺寸沒有變化,這是因為在Y軸上,控制元件只有一個錨點(頂部),然而,在水平方向上,灰色長條是隨著錨點移動而調整尺寸的,因為在X軸上它有兩個錨點,
錨章代表了控制元件錨點所在位置,只要選中了控制元件,錨點標志就會展示在界面上,

如圖所示CounterText和CounterIcon的錨點已經在正確的位置上了,無須再做修改,
接著,我們需要再創建Text和Image控制元件來顯示倒計時,這兩個控制元件則需要手動將其錨點設定在右上角上,
創建倒計時
創建Text控制元件并將其命名為TimerText,設定引數如下:
- Position X: 1225
- Position Y: 50
- Size X: 500
- Size Y: 100
- Font Size: 68
- Justification: Align Text Right(文本向右對齊)

接著,通過長按左鍵拖拽錨點標志,將標志從左上角移到右上角,來修改Text錨點,

可以注意到控制元件位置資訊隨著錨點變化,也相應變化了,

創建Image控制元件并將其命名為TimerIcon,設定引數如下:
- Position X: 1750
- Position Y: 50
- Size To Content: 勾選
- Brush\Image: T_Timer

除了手動調整錨點標志,我們還可以直接使用預設調整錨點,在Details面板點擊Anchors旁邊的下拉框展示預設,選擇第三個預設(帶有右上角小方塊的那個),


UI布局現在已經設定好了,我們可以通過模擬不同螢屏尺寸來檢查錨點設定是否合適,在Designer面板點擊Screen Size下拉框,

WBP_HUD會根據所選項進行尺寸自適應,下圖是HUD在iPad Air上的顯示效果,可以看到控制元件的間隔更近了些,

教程下面的章節,你將學會如何顯示WBP_HUD控制元件,
顯示HUD
點擊Compile并回傳到主編輯器,點進Blueprints檔案夾,并雙擊打開BP_GameManager,
HUD應該在游戲一啟動就顯示,我們在Event BeginPlay節點實作相應邏輯,
找到Event BeginPlay節點,添加Create Widget節點與最后一個節點相連,這個節點會創建特定控制元件實體,

點擊Class下拉框,選擇WBP_HUD,

為了顯示HUD,我們還需要Add to Viewport節點,按住左鍵拖拽Return Value引腳到空白處,在彈出選單中選擇Create Widget進行創建,

讓我們過一遍事件邏輯:
- 一旦Unreal生成BP_GameManager,Restart和SetUpCamera函式就會執行,這些函式會設定一些變數和攝像機,如果你還不知道什么是函式,別擔心,教程后面會有講解,
2.Create Widget節點會創建WBP_HUD實體,
3.Add to Viewport節點顯示WBP_HUD,
點擊Compile節點并回到主編輯器,按下Play在游戲里看看你的新HUD吧,

為了展示計數和倒計時資訊,你需要變數記錄相應資訊,你可以在BP_GameManager看到這些變數,

為了使用這些變數,需要在WBP_HUD里訪問到BP_GameManager,我們可以通過新建變數存盤BP_GameManager參考來達到目的,
存盤參考
存盤參考可以幫助我們快捷地獲取特定物件實體,
想象現在有一個裝著球的盒子,如果你想要找到這顆球,那是非常簡單,因為只存在一個盒子,

現在,再想象有一百個盒子,只有一個盒子裝著球,你就得遍歷所有的盒子才能找到那顆球,

每次你想拿到那顆球,你都得做這樣的一個操作,這樣很快就會導致性能問題,
通過參考,你就能追蹤到裝有球的盒子,這樣,就不用再做遍歷操作了,

創建變數
打開WBP_HUD切換到Graph模式,

在My Blueprint頁簽創建新變數GameManager,
在Details面板點擊Variable Type下拉框,搜索BP_GameManager,并選擇BP Game Manager\Object Reference,

設定參考
點擊Compile并打開BP_GameManager,
找到Create Widget節點,在Return Value引腳按住左鍵拖拽到空白處,選中彈出選單的Set Game Manager,
隨后,將Add to Viewport節點與Set Game Manager節點相連,

注意:通過在雙擊連線,可以添加變更道路節點,長按左鍵拖拽變更道路節點就可以改變連線的走向,
接著,創建Self節點并與Set Game Manager節點左邊的引腳相連,Self節點通過Get a reference to self選單項可以獲取到,

現在,當WBP_HUD創建完后,它可以拿到BP_GameManager的參考,
教程下一部分,你將學習如何通過函式更新控制元件,
函式
在藍圖中,函式是類似于事件圖表的另一種圖表,不同于事件圖表,我們可以通過節點呼叫函式,你可能會問,這么做的意義又是什么呢?

組織性
使用函式的一大原因就是方便組織,通過使用函式,我們可以將多個節點要做的事合成一個節點來完成,
看下BP_GameManager的Event BeginPlay部分邏輯,這里有兩個函式:Restart和SetUpCamera,

如果不用函式,那這部分的邏輯是這樣的:

可以看到,使用函式,整體邏輯看起來更簡潔了,
重用性
使用函式的另一大原因是方便重用,比如,你想要重置計數和倒計時,通過Restart函式就能實作,

每次你想重置變數時,就不需要再創建那么多節點了,
現在弄清楚了函式的用處,我們就使用函式來更新CounterText控制元件吧,
更新控制元件
藍圖默認是訪問不到Text控制元件的,這意味著我們不能設定文本,幸運地是這不難解決,
點擊Compile并打開WBP_HUD,將界面切換到Designer模式,
選中CounterText并在Details面板的頂部,勾選Is Variable勾選框,

現在,我們已經可以更新CounterText了,下一步要做的是創建函式來更新文本,
創建更新函式
將界面切換成Graph模式,點擊My Blueprint頁簽,點擊Functions區域的+號,

這樣會創建出一個新函式,并會自動跳轉到它的圖表界面,這里將函式重命名為UpdateCounterText,
圖表上默認會有一個入口節點,一旦函式被觸發,就是從該節點開始執行,

為了讓CounterText顯示ShapesCollected變數,我們需要手動連接兩者,
將GameManager變數拖拽至圖表,左鍵拖拽引腳到空白處,從彈出選單中選擇Get Shapes Collected節點,

要設定文本,我們需要用到SetText (Text)節點,拖拽CounterText變數至圖表,左鍵拖拽引腳到空白處,從彈出選單中選擇SetText (Text)節點,

SetText (Text)節點只接受Text型別的輸入,而ShapesCollected變數卻是Integer型別變數,幸運地是,當用戶用Integer去連接Text輸入時,會自動進行裝換,
連接ShapesCollected變數和Set Text (Text)節點的In Text引腳,Unreal會自動創建插入ToText (int)節點,

再來看下事件的順序:
- 當外部呼叫UpdateCounterText,函式會從BP_GameManager參考獲取ShapesCollected變數
- ToText (int)節點將ShapesCollected變數轉換成Text型別
- SetText (Text)將來自ToText (int)的值設定給CounterText控制元件
接下來我們要實作,玩家每收集一個圖形,就呼叫一次UpdateCounterText,
呼叫更新函式
在ShapesCollected變數每次自增加一時,呼叫UpdateCounterText是最合適的,我已經先創建好了IncrementShapesCollected函式用于累加計數,每次玩家角色觸碰到掉落的圖形,就會呼叫該函式,

點擊Compile,并回傳到BP_GameManager,
在呼叫UpdateCounterText之前,你還需要獲得WBP_HUD參考,看看你能不能自己存盤獲得參考!
- 找到你創建并顯示WBP_HUD的地方
- 左鍵拖拽Create Widget節點的Return Value引腳
- 在空白處釋放左鍵,從彈出選單中選中Promote to variable
- 將新創建的節點與最后一個節點相連
創建好節點,將其重命名為HUDWidget,

接著,拖拽Set HUDWidget節點右側引腳至空白處,添加UpdateCounterText節點,這樣游戲一開始,CounterText就會顯示ShapesCollected變數值,

隨后在My Blueprint面板的Functions區域,雙擊IncrementShapesCollected打開圖表,

拖拽HUDWidget至圖表,左鍵拖拽引腳至空白處,從彈出選單中添加UpdateCounterText節點并如下圖連接:

現在,只要IncrementShapesCollected執行呼叫,都會累加ShapesCollected并呼叫UpdateCounterText函式,該函式負責將CounterText更新成ShapesCollected的值,
點擊Compile并關閉BP_GameManager,點擊Play運行游戲收集圖形并觀察CounterText變化,

接著,我們會使用另一種叫系結的方法更新TimerText控制元件,
系結
系結允許我們自動更新控制元件的特定引數,可以進行系結的引數,都會有個Bind下拉框,

我們能將控制元件的引數與某個函式或者變數進行系結,系結會持續地從函式或變數中獲得回傳值,并將其賦值給引數,

你可能奇怪那為什么前面不使用系結,由于每幀恒定更新,系結并不是一種很高效率的做法,這意味著即使引數沒有變化,每幀也會浪費時間進行引數更新,相比前面的做法,則只會在數值發生變化時才更新控制元件,
這么說來,系結適用于像倒計時這類更新頻繁的UI元素,接著試試給TimerText創建系結吧,
創建系結
打開WBP_HUD并切換到Designer模式,
選中TimerText,留意Details面板的Content部分,可以看到Text引數是可系結的,點擊Bind下拉框并點擊Create Binding,

這樣會創建新函式并跳轉至它的圖表,將函式重命名為UpdateTimerText,
這個函式會有個Text型別Return Value引腳的Return節點,TimerText會顯示這個引腳所獲得任何文本,

拖拽GameManager至圖表,并獲取TimeRemaining變數,
連接TimeRemaining變數與Return節點的Return Value引腳,像之前一樣,Unreal會自動創建插入轉換節點,

小結:
- 系結會持續呼叫UpdateTimerText函式
- 函式會從BP_GameManager獲取TimeRemaining變數值
- ToText (float)節點會將TimeRemaining變數值轉換成Text型別
- 轉換值會通過Return節點輸出
HUD的邏輯至此全部完成,點擊Compile并關閉WBP_HUD,按下Play運行游戲看下最終效果,

后續學習
你可以在這里下載完整專案,
現在你已經了解了UMG的基礎知識,構建更復雜點的界面也不再是難事,多多嘗試其他控制元件吧,
如果想了解更多控制元件的用處,請前往Unreal引擎檔案的控制元件型別參考頁,
如果你還想繼續學習引擎其他內容,點擊下篇教程,將教你如何整合已學知識,制作一個簡單游戲!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/10668.html
標籤:其他
