Godot Engine Walk-through | 基礎UI結構



繼續進行官方文件的step by step部分,這次要做的是簡易UI實作。

而遊戲裡使用者介面的目標:讓玩家能夠輕鬆理解遊戲裡的資訊、以及透過介面操作來與遊戲做互動,並且呢,依據不同的遊戲類型,有時需要很多的反饋跟提示。
之前看的有部影片總結了好的遊戲UI設計的最後效果:讓玩家感覺到非常自然且舒適,渾然像是自己的另外一隻四肢。








Godot Engine實作UI方式有兩種

What do we do?

  • 簡易性
    這裡先不談比較進階的反饋性或提示性元素,因為那些牽扯到動畫系統和viewport的操作,先做最基本功能性的元件(像是選單、按鈕、文字、圖示...)
  • 響應式
    現代設計需要建構responsive的使用者介面,像是網頁/手機app需要考慮眾多規格的螢幕和解析度,不同規格就會'流'成不同樣式的介面,但遊戲UI不需要那摸responsive,例如PC遊戲就只要考量PC玩家的裝置就好,稍微放大寬高、可以正常縮放UI介面就OK了

 How do we do?

  1. 使用anchor定位:無並排結構時使用,hiearchy乾淨
  2. 使用nested container:存在並排結構(大多數時候)
 但是在介紹兩種方法之前,先介紹一下構成UI的基本元素:Godot的control node


常用control node介紹 

Godot的node依繼承關係分為四類:
3D(Spatial)、[2D(Node2D)、UI(Control)] (CanvasItem)、其他,其中要介紹的就是組成使用者介面的control node。
最基本的五種如下,後面標示相似功能或相關的node
  • 顯示底色:Panel  /NinePatchRect/PanelContainer/ColorRect
  • 顯示文字:Label  /RichTextLabel
  • 顯示圖片:TextureRect
  • 按鈕類,接受input產生回應:Button  /TextureButton
  • 進度類,提示某數值的狀態:ProgressBar  /TextureProgress




使用anchor定位

有了基本node的認識,來實作一個簡易的UI介面。

圖中的打鳥手遊UI非常簡易,只有三個Button、一個Label,而且他們之間沒有堆疊並列關係,這種情形就可以只用anchor定位,將他們分別加入場景後,在工具列上的layout調整每個node的anchor即可(暫停按鈕設在左上、顯示label設在上中...)

這邊要注意的是,官方說明文件中,講解引擎內UI系統使用了三個概念決定control node的位置和大小:Anchor、Margin、Rect
  • Anchor:此control node的參考點相對於其parent要定位在哪裡,左0.25表示左參考點位於parent rect從左側開始算四分之一的位置、右0.75表示右參考點位於parent rect從左側開始算四分之三的位置,以此類推...(ps.按H可以開啟anchor提示)
  • Margin:此control node的rect邊界相對於其參考點距離多遠,左40px表示rect的左邊界在目前左參考點往右邊40像素的位置、右-40px表示rect的右邊界在目前右參考點往左邊40像素的位置
  • Rect:此control node的bounding box,大小由使用者決定,位置會由上面兩個值得出,並且bounding box不可以比content還要小(而每個control node的content規則也不同,如縮放一個按鈕的rect時,使用預設設定最小只能縮到剛好顯示所有文字的大小)

然後理解他們用處後,興奮的新手(94窩)就會開始直接移動node的位置、調整anchor和margin的數值,which is totally fucked up!
因為些屬性本來就是設計給UI系統內部用來計算的,不需要刻意調整,另外刻意調整anchor會發現node位置根本就沒動,因為引擎又自動算一遍更新了margin...
而調整大小後發現也不會依據目前anchor協定更新位置,再一次的、引擎又幫你更動了margin來延伸大小,沒有更新此node相對於parent的比例位置...

所以當使用這種方法時,要記得先設定好rect大小,再到工具列設定Layout,其他的就不需要動。這邊用影片簡短示範如何做出上述簡單UI,並且給予一個與螢幕的小間隔。


使用nested container

如果介面開始複雜、有相互堆疊或並排的架構,那就必須依賴container node的幫助,藉由這些container來決定每層node的原生屬性,來產生更複雜的responsive效果,概念很像Qt framework:把UI看成是一個個相互包含的區塊。
在實作之前來介紹一下幾個container種類和另外一個control node的屬性:size-flag

常見container

  • HBoxContainer:將其(第一層的,下略)children以水平方式並排
  • VBoxContainer:將其children以垂直方式並排
  • GridContainer:將其children以row major的方式排列成矩陣,可以指定columns數
  • CenterContainer:將其所有children都置中(so通常一個child),且不對其rect做scale
  • MarginContainer:將其所有children都以指定距離往內隔(通常一個child)
  • PanelContainer:提供其所有children一個基底,且不對其rect做scale

Container的特性就是會對其children做某個形式的排版,並且上層的node改動大小的時候,也會更新底下階層的大小,所以當Container裡面包的是另外一個Container,那就可以實現較複雜的responsive UI結構。

底下的grid不知道為什麼bounding box有問題,有可能是引擎的bug


Size Flags屬性

有了container還不夠,有時候我們需要讓元件伸展、或往某個地方靠,那就要透過size flag來規定元件行為。
Horizontal / Vertical flag
Fill:是否填滿其佔有空間
Expand:是否嘗試往外側推移、來增加其佔有空間
Shrink Center:移動至其佔有空間的中間(非fill狀態才看得出差異)
Shrink End:移動至其佔有空間的另一側(非fill狀態才看得出差異)
Stretch Ratio:expand的擴張比例,預設都是1

另外,對於HBoxContainer來說,vertical flag設為fill相當於fill+expand,因為元件在垂直方向上不會遇到其他人,所以會主動向外expand,這個狀況可以延伸到VBoxContainer,而GridContainer因為在兩個方向都會有其他元件,所以不會出現這樣的行為(就算某方向沒有,例如1x5,也不會出現)。



還有size flag對於CenterContainer/MarginContainer的效用也會被限制,總而言之size flag屬性蠻不統一的,需要多方面嘗試才能確認其行為。


分析介面邏輯 / 進行區塊切割

接著搭配container+size flags就可以實作出比較複雜的responsive介面,但是需要先對設計做切割,區分哪一塊要用什麼container、是否可用size flag達成需求,以官方的素材為例,上面的戰鬥UI可以被切成這樣:


切完之後就可以由上至下開始擺放control node了,而這時候也應該使用scene inheritence來加速prototype的流程(屌虐Unity的功能!)、注意如果需要改動繼承其他scene的素材,要記得make resource unique。
一樣用影片簡短解釋與示範:



留言

  1. Slot Machine - Dr.MCD
    I will give you 하남 출장샵 my very best 제주 출장안마 review of 대구광역 출장마사지 the best online slots by Jackpot City and I will cover it 삼척 출장안마 with real money play. There is also an option for a 1xbet 먹튀

    回覆刪除

張貼留言

熱門文章