原文:Unreal Engine 4 UI Tutorial
做者:Tommy Tran
譯者:Shuchang Liuhtml
在本篇教程,你將學會如何建立,展現和更新一個HUD界面。web
在遊戲中,開發者使用圖像和文字來展現玩家血條,得分等相關信息,這就是用戶界面(UI)。app
你能夠在Unreal Engine 4裏利用Unreal Motion Graphics(UMG)。UMG容許你經過拖拽按鈕,文本等UI元素來構建UI界面。編輯器
在本篇教程,你將學會:ide
請注意,本篇教程涉及藍圖內容。若是你須要複習有關內容,請查看藍圖教程。svg
注意:本篇教程只是Unreal Engine 4系列教程的其中一篇:函數
下載示例項目並解壓。進入項目文件夾,雙擊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由七個主要元素組成:
Text控件很是適合展現像計數和倒計時這樣的數字信息。
在Palette面板搜索Text控件。經過按住左鍵拖拽控件至Designer面板。
別在乎文本內容,等等咱們會替換它。
先選中Text控件,在Details面板頂部的文本框輸入CounterText進行重命名。
你能夠在Designer面板經過長按左鍵拖拽控件。
你也能夠經過左鍵點擊拖拉選中框來調整控件的大小。這樣能夠調整控件的包圍框。Unreal引擎不會渲染包圍框以外的內容。
一樣的,你能夠經過Details面板輸入數值來修改控件的位置和大小。設置CounterText以下:
此時文本只佔了包圍框很小一部分顯示。
咱們能夠在Detail面板的Appearance設置調大字體大小。在Font屬性的最右側文本框能夠設置字體大小。
將字體大小調成68。
接着咱們再在文本框旁添加一個圖標來提高視覺效果。
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。設置參數以下:
接着,經過長按左鍵拖拽錨點標誌,將標誌從左上角移到右上角,來修改Text錨點。
能夠注意到控件位置信息隨着錨點變化,也相應變化了。
建立Image控件並將其命名爲TimerIcon。設置參數以下:
除了手動調整錨點標誌,咱們還能夠直接使用預設調整錨點。在Details面板點擊Anchors旁邊的下拉框展現預設。選擇第三個預設(帶有右上角小方塊的那個)。
UI佈局如今已經設置好了。咱們能夠經過模擬不一樣屏幕尺寸來檢查錨點設置是否合適。在Designer面板點擊Screen Size下拉框。
WBP_HUD會根據所選項進行尺寸自適應。下圖是HUD在iPad Air上的顯示效果。能夠看到控件的間隔更近了些。
教程下面的章節,你將學會如何顯示WBP_HUD控件。
點擊Compile並返回到主編輯器。點進Blueprints文件夾,並雙擊打開BP_GameManager。
HUD應該在遊戲一啓動就顯示。咱們在Event BeginPlay節點實現相應邏輯。
找到Event BeginPlay節點,添加Create Widget節點與最後一個節點相連。這個節點會建立特定控件實例。
點擊Class下拉框,選擇WBP_HUD。
爲了顯示HUD,咱們還須要Add to Viewport節點。按住左鍵拖拽Return Value引腳到空白處,在彈出菜單中選擇Create Widget進行建立。
讓咱們過一遍事件邏輯:
點擊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。
在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會自動建立插入轉換節點。
小結:
HUD的邏輯至此所有完成。點擊Compile並關閉WBP_HUD。按下Play運行遊戲看下最終效果。
你能夠在這裏下載完整項目。
如今你已經瞭解了UMG的基礎知識,構建更復雜點的界面也再也不是難事。多多嘗試其餘控件吧。
若是想了解更多控件的用處,請前往Unreal引擎文檔的控件類型參考頁。
若是你還想繼續學習引擎其餘內容,點擊下篇教程,將教你如何整合已學知識,製做一個簡單遊戲!