Unreal Engine 4 系列教程 Part 4:UI教程

原文:Unreal Engine 4 UI Tutorial
作者:Tommy Tran
譯者:Shuchang Liu

在本篇教程,你將學(xué)會(huì)如何創(chuàng)建,展示和更新一個(gè)HUD界面。

在游戲中,開(kāi)發(fā)者使用圖像和文字來(lái)展示玩家血條,得分等相關(guān)信息,這就是用戶界面(UI)。

你可以在Unreal Engine 4里利用Unreal Motion Graphics(UMG)。UMG允許你通過(guò)拖拽按鈕,文本等UI元素來(lái)構(gòu)建UI界面。

在本篇教程,你將學(xué)會(huì):

  1. 創(chuàng)建展示得分和時(shí)間的HUD
  2. 展示HUD
  3. 當(dāng)變量值變化時(shí),更新得分和時(shí)間顯示

請(qǐng)注意,本篇教程涉及藍(lán)圖內(nèi)容。如果你需要復(fù)習(xí)有關(guān)內(nèi)容,請(qǐng)查看藍(lán)圖教程

注意:本篇教程只是Unreal Engine 4系列教程的其中一篇:

起步入門(mén)

下載示例項(xiàng)目并解壓。進(jìn)入項(xiàng)目文件夾,雙擊BananaCollector.uproject打開(kāi)項(xiàng)目。

注意:如果你看到了項(xiàng)目是由較早的引擎版本創(chuàng)建的提示,這很正常(因?yàn)橐娼?jīng)常更新版本)。你可以選擇以拷貝副本的形式打開(kāi),也可以直接轉(zhuǎn)換項(xiàng)目版本打開(kāi)。

點(diǎn)擊Play開(kāi)始游戲,控制白色方塊接住掉落的圖形。你可以通過(guò)移動(dòng)鼠標(biāo)平移方塊。10秒后,圖形會(huì)停止掉落。

我們要做的第一件事就是創(chuàng)建HUD展示兩個(gè)信息:

  • 玩家收集了多少個(gè)圖形的計(jì)數(shù)
  • 距離圖形停止掉落的倒計(jì)時(shí)

其中需要使用到Widgets(控件)

關(guān)于控件

控件是一種提供簡(jiǎn)單功能的UI元素。比如,按鈕控件提供了玩家可見(jiàn)可點(diǎn)擊的物體。

控件本身不一定是可視的。比如,網(wǎng)格面板掛件只是用于平均排布子元素。玩家看不見(jiàn)控件本身,但能看到控件的效果。

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

你甚至可以創(chuàng)建一個(gè)鋪滿屏幕的控件。比如下面的控件作為一個(gè)標(biāo)題界面鋪滿了屏幕。這個(gè)控件所包含了其他UI元素也都為控件。

了解完什么是控件,現(xiàn)在動(dòng)手創(chuàng)建一個(gè)。

創(chuàng)建控件

Content Browser界面進(jìn)入UI文件夾。點(diǎn)擊Add New按鈕,選擇創(chuàng)建User Interface\Widget Blueprint,將其重名為WBP_HUD

雙擊WBP_HUD打開(kāi)UMG UI Designer。

UMG UI Designer

UMG UI Designer由七個(gè)主要元素組成:

  1. Designer:這個(gè)區(qū)域展示所選控件的外觀。通過(guò)長(zhǎng)按右鍵移動(dòng)鼠標(biāo)拖動(dòng)面板,滑動(dòng)滾輪縮放面板。
  2. Details:展示所選控件的參數(shù)
  3. Palette:可用控件列表
  4. Hierarchy:當(dāng)前所使用的控件列表
  5. Animations:控件能夠基于位置,大小等外觀參數(shù)制作動(dòng)畫(huà)效果。該面板展示控件的所有動(dòng)畫(huà)
  6. Timeline:當(dāng)你選中動(dòng)畫(huà)時(shí),該面板會(huì)展示對(duì)應(yīng)的動(dòng)畫(huà)參數(shù)和關(guān)鍵幀
  7. Editor Mode:通過(guò)該按鈕可以切換編輯器的Designer和Graph模式。Graph模式的編輯器顯示類似于藍(lán)圖的Event Graph。

創(chuàng)建Text控件

Text控件非常適合展示像計(jì)數(shù)和倒計(jì)時(shí)這樣的數(shù)字信息。

在Palette面板搜索Text控件。通過(guò)按住左鍵拖拽控件至Designer面板。

別在意文本內(nèi)容,等等我們會(huì)替換它。

先選中Text控件,在Details面板頂部的文本框輸入CounterText進(jìn)行重命名。

你可以在Designer面板通過(guò)長(zhǎng)按左鍵拖拽控件。

你也可以通過(guò)左鍵點(diǎn)擊拖拉選中框來(lái)調(diào)整控件的大小。這樣可以調(diào)整控件的包圍框。Unreal引擎不會(huì)渲染包圍框之外的內(nèi)容。

同樣的,你可以通過(guò)Details面板輸入數(shù)值來(lái)修改控件的位置和大小。設(shè)置CounterText如下:

  • Position X: 200
  • Position Y: 50
  • Size X: 500
  • Size Y: 100

此時(shí)文本只占了包圍框很小一部分顯示。

我們可以在Detail面板的Appearance設(shè)置調(diào)大字體大小。在Font屬性的最右側(cè)文本框可以設(shè)置字體大小。

將字體大小調(diào)成68

接著我們?cè)僭谖谋究蚺蕴砑右粋€(gè)圖標(biāo)來(lái)提升視覺(jué)效果。

創(chuàng)建Image控件

Image控件可以讓我們展示像圖標(biāo)一類的UI圖形。

創(chuàng)建Image控件并將其命名為CounterIcon。將Position X設(shè)成75Position Y設(shè)成50,顯示在CounterText左邊。

接著在Details面板的Appearance設(shè)置顯示圖片。展開(kāi)Brush設(shè)置,點(diǎn)擊Image字段下拉框,選擇T_Counter

由于控件與圖片的長(zhǎng)寬不一樣,圖片看起來(lái)擠壓變形了。

除了手動(dòng)調(diào)整控件大小,我們還可以使用Size To Content選項(xiàng)來(lái)調(diào)整控件大小。該選項(xiàng)會(huì)自動(dòng)將控件大小調(diào)整成圖片大小。

點(diǎn)開(kāi)Details面板的Slot(Canvas Panel Slot)部分設(shè)置,勾選Size To Content 選中框

控件會(huì)適應(yīng)調(diào)整成圖片的大小。

當(dāng)游戲在不同屏幕尺寸下運(yùn)行時(shí),UI控件需要根據(jù)情況調(diào)整顯示位置。為了保持UI的布局,我們可以使用錨點(diǎn)

錨點(diǎn)

錨點(diǎn)確定了控件位置的相對(duì)參考點(diǎn)。控件的錨點(diǎn)默認(rèn)為其父對(duì)象的左上角。所以,當(dāng)我們?cè)诮o一個(gè)控件設(shè)位置時(shí),其實(shí)是在設(shè)控件相對(duì)于錨點(diǎn)的位置。

下圖例子里,每個(gè)Image都以一個(gè)點(diǎn)作為它們的錨點(diǎn)(距離自身最近的角落點(diǎn))。

注意看每個(gè)Image是怎么與錨點(diǎn)保持相對(duì)位置的。合理利用錨點(diǎn),就可以保證UI元素在不同屏幕尺寸上都保持統(tǒng)一布局。

我們也可以利用錨點(diǎn)來(lái)自動(dòng)調(diào)整控件的大小。當(dāng)錨點(diǎn)多于兩個(gè)點(diǎn)或更多時(shí),控件會(huì)根據(jù)屏幕尺寸調(diào)整大小來(lái)保持它的相對(duì)尺寸。

下圖例子里,灰色長(zhǎng)條的錨點(diǎn)為左上角和右上角。

在垂直方向上,灰色長(zhǎng)條隨著錨點(diǎn)移動(dòng),但尺寸沒(méi)有變化。這是因?yàn)樵赮軸上,控件只有一個(gè)錨點(diǎn)(頂部)。然而,在水平方向上,灰色長(zhǎng)條是隨著錨點(diǎn)移動(dòng)而調(diào)整尺寸的,因?yàn)樵赬軸上它有兩個(gè)錨點(diǎn)。

錨章代表了控件錨點(diǎn)所在位置,只要選中了控件,錨點(diǎn)標(biāo)志就會(huì)展示在界面上。

如圖所示CounterTextCounterIcon的錨點(diǎn)已經(jīng)在正確的位置上了,無(wú)須再做修改。

接著,我們需要再創(chuàng)建Text和Image控件來(lái)顯示倒計(jì)時(shí)。這兩個(gè)控件則需要手動(dòng)將其錨點(diǎn)設(shè)置在右上角上。

創(chuàng)建倒計(jì)時(shí)

創(chuàng)建Text控件并將其命名為TimerText。設(shè)置參數(shù)如下:

  • Position X: 1225
  • Position Y: 50
  • Size X: 500
  • Size Y: 100
  • Font Size: 68
  • Justification: Align Text Right(文本向右對(duì)齊)

接著,通過(guò)長(zhǎng)按左鍵拖拽錨點(diǎn)標(biāo)志,將標(biāo)志從左上角移到右上角,來(lái)修改Text錨點(diǎn)。

可以注意到控件位置信息隨著錨點(diǎn)變化,也相應(yīng)變化了。

創(chuàng)建Image控件并將其命名為TimerIcon。設(shè)置參數(shù)如下:

  • Position X: 1750
  • Position Y: 50
  • Size To Content: 勾選
  • Brush\Image: T_Timer

除了手動(dòng)調(diào)整錨點(diǎn)標(biāo)志,我們還可以直接使用預(yù)設(shè)調(diào)整錨點(diǎn)。在Details面板點(diǎn)擊Anchors旁邊的下拉框展示預(yù)設(shè)。選擇第三個(gè)預(yù)設(shè)(帶有右上角小方塊的那個(gè))。

UI布局現(xiàn)在已經(jīng)設(shè)置好了。我們可以通過(guò)模擬不同屏幕尺寸來(lái)檢查錨點(diǎn)設(shè)置是否合適。在Designer面板點(diǎn)擊Screen Size下拉框

WBP_HUD會(huì)根據(jù)所選項(xiàng)進(jìn)行尺寸自適應(yīng)。下圖是HUD在iPad Air上的顯示效果。可以看到控件的間隔更近了些。

教程下面的章節(jié),你將學(xué)會(huì)如何顯示WBP_HUD控件。

顯示HUD

點(diǎn)擊Compile并返回到主編輯器。點(diǎn)進(jìn)Blueprints文件夾,并雙擊打開(kāi)BP_GameManager

HUD應(yīng)該在游戲一啟動(dòng)就顯示。我們?cè)?strong>Event BeginPlay節(jié)點(diǎn)實(shí)現(xiàn)相應(yīng)邏輯。

找到Event BeginPlay節(jié)點(diǎn),添加Create Widget節(jié)點(diǎn)與最后一個(gè)節(jié)點(diǎn)相連。這個(gè)節(jié)點(diǎn)會(huì)創(chuàng)建特定控件實(shí)例。

點(diǎn)擊Class下拉框,選擇WBP_HUD

為了顯示HUD,我們還需要Add to Viewport節(jié)點(diǎn)。按住左鍵拖拽Return Value引腳到空白處,在彈出菜單中選擇Create Widget進(jìn)行創(chuàng)建。

讓我們過(guò)一遍事件邏輯:

  1. 一旦Unreal生成BP_GameManagerRestartSetUpCamera函數(shù)就會(huì)執(zhí)行。這些函數(shù)會(huì)設(shè)置一些變量和攝像機(jī)。如果你還不知道什么是函數(shù),別擔(dān)心。教程后面會(huì)有講解。
    2.Create Widget節(jié)點(diǎn)會(huì)創(chuàng)建WBP_HUD實(shí)例。
    3.Add to Viewport節(jié)點(diǎn)顯示WBP_HUD

點(diǎn)擊Compile節(jié)點(diǎn)并回到主編輯器。按下Play在游戲里看看你的新HUD吧。

為了展示計(jì)數(shù)和倒計(jì)時(shí)信息,你需要變量記錄相應(yīng)信息。你可以在BP_GameManager看到這些變量。

為了使用這些變量,需要在WBP_HUD里訪問(wèn)到BP_GameManager。我們可以通過(guò)新建變量存儲(chǔ)BP_GameManager引用來(lái)達(dá)到目的。

存儲(chǔ)引用

存儲(chǔ)引用可以幫助我們快捷地獲取特定對(duì)象實(shí)例。

想象現(xiàn)在有一個(gè)裝著球的盒子。如果你想要找到這顆球,那是非常簡(jiǎn)單,因?yàn)橹淮嬖谝粋€(gè)盒子。

現(xiàn)在,再想象有一百個(gè)盒子,只有一個(gè)盒子裝著球。你就得遍歷所有的盒子才能找到那顆球。

每次你想拿到那顆球,你都得做這樣的一個(gè)操作。這樣很快就會(huì)導(dǎo)致性能問(wèn)題。

通過(guò)引用,你就能追蹤到裝有球的盒子。這樣,就不用再做遍歷操作了。

創(chuàng)建變量

打開(kāi)WBP_HUD切換到Graph模式。

在My Blueprint頁(yè)簽創(chuàng)建新變量GameManager

在Details面板點(diǎn)擊Variable Type下拉框。搜索BP_GameManager,并選擇BP Game Manager\Object Reference

設(shè)置引用

點(diǎn)擊Compile并打開(kāi)BP_GameManager

找到Create Widget節(jié)點(diǎn),在Return Value引腳按住左鍵拖拽到空白處,選中彈出菜單的Set Game Manager

隨后,將Add to Viewport節(jié)點(diǎn)與Set Game Manager節(jié)點(diǎn)相連。

注意:通過(guò)在雙擊連線,可以添加變更道路節(jié)點(diǎn)。長(zhǎng)按左鍵拖拽變更道路節(jié)點(diǎn)就可以改變連線的走向。

接著,創(chuàng)建Self節(jié)點(diǎn)并與Set Game Manager節(jié)點(diǎn)左邊的引腳相連。Self節(jié)點(diǎn)通過(guò)Get a reference to self菜單項(xiàng)可以獲取到。

現(xiàn)在,當(dāng)WBP_HUD創(chuàng)建完后,它可以拿到BP_GameManager的引用。

教程下一部分,你將學(xué)習(xí)如何通過(guò)函數(shù)更新控件。

函數(shù)

在藍(lán)圖中,函數(shù)是類似于事件圖表的另一種圖表。不同于事件圖表,我們可以通過(guò)節(jié)點(diǎn)調(diào)用函數(shù)。你可能會(huì)問(wèn),這么做的意義又是什么呢?

組織性

使用函數(shù)的一大原因就是方便組織。通過(guò)使用函數(shù),我們可以將多個(gè)節(jié)點(diǎn)要做的事合成一個(gè)節(jié)點(diǎn)來(lái)完成。

看下BP_GameManagerEvent BeginPlay部分邏輯,這里有兩個(gè)函數(shù):RestartSetUpCamera

如果不用函數(shù),那這部分的邏輯是這樣的:

可以看到,使用函數(shù),整體邏輯看起來(lái)更簡(jiǎn)潔了。

重用性

使用函數(shù)的另一大原因是方便重用。比如,你想要重置計(jì)數(shù)和倒計(jì)時(shí),通過(guò)Restart函數(shù)就能實(shí)現(xiàn)。

每次你想重置變量時(shí),就不需要再創(chuàng)建那么多節(jié)點(diǎn)了。

現(xiàn)在弄清楚了函數(shù)的用處,我們就使用函數(shù)來(lái)更新CounterText控件吧。

更新控件

藍(lán)圖默認(rèn)是訪問(wèn)不到Text控件的。這意味著我們不能設(shè)置文本。幸運(yùn)地是這不難解決。

點(diǎn)擊Compile并打開(kāi)WBP_HUD。將界面切換到Designer模式。

選中CounterText并在Details面板的頂部,勾選Is Variable勾選框

現(xiàn)在,我們已經(jīng)可以更新CounterText了。下一步要做的是創(chuàng)建函數(shù)來(lái)更新文本。

創(chuàng)建更新函數(shù)

將界面切換成Graph模式,點(diǎn)擊My Blueprint頁(yè)簽,點(diǎn)擊Functions區(qū)域的+號(hào)。

這樣會(huì)創(chuàng)建出一個(gè)新函數(shù),并會(huì)自動(dòng)跳轉(zhuǎn)到它的圖表界面。這里將函數(shù)重命名為UpdateCounterText

圖表上默認(rèn)會(huì)有一個(gè)入口節(jié)點(diǎn)。一旦函數(shù)被觸發(fā),就是從該節(jié)點(diǎn)開(kāi)始執(zhí)行。

為了讓CounterText顯示ShapesCollected變量,我們需要手動(dòng)連接兩者。

GameManager變量拖拽至圖表。左鍵拖拽引腳到空白處,從彈出菜單中選擇Get Shapes Collected節(jié)點(diǎn)。

要設(shè)置文本,我們需要用到SetText (Text)節(jié)點(diǎn)。拖拽CounterText變量至圖表。左鍵拖拽引腳到空白處,從彈出菜單中選擇SetText (Text)節(jié)點(diǎn)。

SetText (Text)節(jié)點(diǎn)只接受Text類型的輸入,而ShapesCollected變量卻是Integer類型變量。幸運(yùn)地是,當(dāng)用戶用Integer去連接Text輸入時(shí),會(huì)自動(dòng)進(jìn)行裝換。

連接ShapesCollected變量和Set Text (Text)節(jié)點(diǎn)In Text引腳,Unreal會(huì)自動(dòng)創(chuàng)建插入ToText (int)節(jié)點(diǎn)。

再來(lái)看下事件的順序:

  1. 當(dāng)外部調(diào)用UpdateCounterText,函數(shù)會(huì)從BP_GameManager引用獲取ShapesCollected變量
  2. ToText (int)節(jié)點(diǎn)將ShapesCollected變量轉(zhuǎn)換成Text類型
  3. SetText (Text)將來(lái)自ToText (int)的值設(shè)置給CounterText控件

接下來(lái)我們要實(shí)現(xiàn),玩家每收集一個(gè)圖形,就調(diào)用一次UpdateCounterText

調(diào)用更新函數(shù)

ShapesCollected變量每次自增加一時(shí),調(diào)用UpdateCounterText是最合適的。我已經(jīng)先創(chuàng)建好了IncrementShapesCollected函數(shù)用于累加計(jì)數(shù)。每次玩家角色觸碰到掉落的圖形,就會(huì)調(diào)用該函數(shù)。

點(diǎn)擊Compile,并返回到BP_GameManager

在調(diào)用UpdateCounterText之前,你還需要獲得WBP_HUD引用,看看你能不能自己存儲(chǔ)獲得引用!

  • 找到你創(chuàng)建并顯示WBP_HUD的地方
  • 左鍵拖拽Create Widget節(jié)點(diǎn)Return Value引腳
  • 空白處釋放左鍵,從彈出菜單中選中Promote to variable
  • 將新創(chuàng)建的節(jié)點(diǎn)與最后一個(gè)節(jié)點(diǎn)相連

創(chuàng)建好節(jié)點(diǎn),將其重命名為HUDWidget

接著,拖拽Set HUDWidget節(jié)點(diǎn)右側(cè)引腳至空白處,添加UpdateCounterText節(jié)點(diǎn)。這樣游戲一開(kāi)始,CounterText就會(huì)顯示ShapesCollected變量值。

隨后在My Blueprint面板的Functions區(qū)域,雙擊IncrementShapesCollected打開(kāi)圖表。

拖拽HUDWidget至圖表,左鍵拖拽引腳至空白處,從彈出菜單中添加UpdateCounterText節(jié)點(diǎn)并如下圖連接:

現(xiàn)在,只要IncrementShapesCollected執(zhí)行調(diào)用,都會(huì)累加ShapesCollected并調(diào)用UpdateCounterText函數(shù)。該函數(shù)負(fù)責(zé)將CounterText更新成ShapesCollected的值。

點(diǎn)擊Compile并關(guān)閉BP_GameManager。點(diǎn)擊Play運(yùn)行游戲收集圖形并觀察CounterText變化。

接著,我們會(huì)使用另一種叫綁定的方法更新TimerText控件。

綁定

綁定允許我們自動(dòng)更新控件的特定參數(shù)。可以進(jìn)行綁定的參數(shù),都會(huì)有個(gè)Bind下拉框

我們能將控件的參數(shù)與某個(gè)函數(shù)或者變量進(jìn)行綁定。綁定會(huì)持續(xù)地從函數(shù)或變量中獲得返回值,并將其賦值給參數(shù)。

你可能奇怪那為什么前面不使用綁定。由于每幀恒定更新,綁定并不是一種很高效率的做法。這意味著即使參數(shù)沒(méi)有變化,每幀也會(huì)浪費(fèi)時(shí)間進(jìn)行參數(shù)更新。相比前面的做法,則只會(huì)在數(shù)值發(fā)生變化時(shí)才更新控件。

這么說(shuō)來(lái),綁定適用于像倒計(jì)時(shí)這類更新頻繁的UI元素。接著試試給TimerText創(chuàng)建綁定吧。

創(chuàng)建綁定

打開(kāi)WBP_HUD并切換到Designer模式。

選中TimerText,留意Details面板的Content部分。可以看到Text參數(shù)是可綁定的。點(diǎn)擊Bind下拉框并點(diǎn)擊Create Binding

這樣會(huì)創(chuàng)建新函數(shù)并跳轉(zhuǎn)至它的圖表。將函數(shù)重命名為UpdateTimerText

這個(gè)函數(shù)會(huì)有個(gè)Text類型Return Value引腳Return節(jié)點(diǎn)。TimerText會(huì)顯示這個(gè)引腳所獲得任何文本。

拖拽GameManager至圖表,并獲取TimeRemaining變量。

連接TimeRemaining變量與Return節(jié)點(diǎn)的Return Value引腳。像之前一樣,Unreal會(huì)自動(dòng)創(chuàng)建插入轉(zhuǎn)換節(jié)點(diǎn)。

小結(jié):

  • 綁定會(huì)持續(xù)調(diào)用UpdateTimerText函數(shù)
  • 函數(shù)會(huì)從BP_GameManager獲取TimeRemaining變量值
  • ToText (float)節(jié)點(diǎn)會(huì)將TimeRemaining變量值轉(zhuǎn)換成Text類型
  • 轉(zhuǎn)換值會(huì)通過(guò)Return節(jié)點(diǎn)輸出

HUD的邏輯至此全部完成。點(diǎn)擊Compile并關(guān)閉WBP_HUD。按下Play運(yùn)行游戲看下最終效果。

后續(xù)學(xué)習(xí)

你可以在這里下載完整項(xiàng)目。

現(xiàn)在你已經(jīng)了解了UMG的基礎(chǔ)知識(shí),構(gòu)建更復(fù)雜點(diǎn)的界面也不再是難事。多多嘗試其他控件吧。

如果想了解更多控件的用處,請(qǐng)前往Unreal引擎文檔的控件類型參考頁(yè)。

如果你還想繼續(xù)學(xué)習(xí)引擎其他內(nèi)容,點(diǎn)擊下篇教程,將教你如何整合已學(xué)知識(shí),制作一個(gè)簡(jiǎn)單游戲!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容