3D Game Programming & Design:UI系統--Quest Log 公告牌

UI系統概述

UI 即 User Interface(用戶界面)的簡稱。在許多軟件中,採用狹義的概念,特指窗體、面板、按鈕、文本框等人們熟悉的人機交互元素,及其組織與風格(也稱皮膚)。Unity UI 系統採用上述狹義概念。

5.0 及以後 - Unity GUI / UGUI 是面向對象的 UI 系統。所有 UI 元素都是遊戲對象,友好的圖形化設計界面, 可在場景渲染階段渲染這些 UI 元素。

  • UGUI 的產生與優勢

    隨着遊戲開發的普及,爲了讓設計師也能參與參與程序開發,從簡單的地圖編輯器、菜單編輯器等工具應運而生。設計師甚至不需要程序員幫助,使用這些工具就可直接創造遊戲元素,乃至產生遊戲程序。除此之外,現代遊戲 UI 必須要滿足以下要求:

    • 跨設備執行,自動適應不同分辨率
    • UI 元素與遊戲場景融爲一體的交互
    • 支持複雜的佈局
    • 多攝像機支持

    以至於即使優秀的程序員在現代 UI 面前,傳統代碼驅動的 UI 面臨開發效率低下,難以調試等問題。 對於 Unity 平臺, 當 NGUI: Next-Gen UI kit 的出現使得不依賴 Unity Pro 功能,使用所見即所得(WYSIWYG)設計工具,集成了 tweening 運動管理系統, 可以製作多數 2D 遊戲,直接威脅了 Unity 的生意。 Unity 最終高薪聘了 NGUI 的主設計師,最終又分道揚鑣,於是就有了 UGUI,青出於藍而勝於藍!

    UGUI 的優勢:

    • 所見即所得(WYSIWYG)設計工具
    • 支持多模式、多攝像機渲染
    • 面向對象的編程

UGUI 基礎

畫布(Cavas)

畫布(Cavas)是繪圖區域, 同時是 ui 元素的容器。 容器中 ui 元素及其子 UI 元素都將繪製在其上。 擁有Canvas組件的遊戲對象都有一個畫布,它空間中的子對象,如果是 UI 元素將渲染在畫布上。畫布區域在場景視圖中顯示爲矩形。這使得定位UI元素變得非常容易,無需隨時顯示遊戲運行視圖。

UI 佈局基礎

每個UI元素都被表示爲一個矩形,爲了相對於 Canvas 和 其他 UI 元素實現定位,Unity 在 Transform 基礎上定義了 RectTransform (矩形變換) 支持矩形元素在 2/3D 場景中變換。

UI 組件與元素

UI 部件都是用 Script 開發的自定義組件。包括在 UI、Layout 和 Rendering 等分類中。

1、可視化組件

可視化組件,在組件 UI 分類中,包括:

  • Text:顯示的文本的文本區域。可以設置字體,字體樣式,字體大小以及文本是否具有豐富的文本功能。
  • Image:顯示圖片的區域。可以設置GUI精靈、色彩。
  • Raw Image:原始圖像採用紋理,進行 UV 矩形貼圖。
  • Mask:Mask不是一個可見的UI控件。遮罩將子元素限制(即“掩蔽”)爲父元素的形狀。如果孩子比父控件大,那麼只有適合父節點遮罩的部分是可見的。
    Effects:應用各種簡單的效果,例如簡單的投影或輪廓。

2、UI 交互元素

UI 交互元素是 GameObject,它擁有 UI 交互組件、UI可視化組件、及相關組件的組合,以及一些 UI 子元素構成,以方便用戶在設計場景中創建交互界面。

例如:Button 元素,除了 UI 必須擁有的 RectTransform 和 Canvas renderer 外,還有 Image 和 Button 組件,以及一個 Text 子元素。

  • Button
  • Toggle
  • Toggle Group
  • Slider
  • Scrollbar
  • Dropdown
  • Input Field
  • Scroll Rect (Scroll View)

其他更多關於UI系統的基礎操作知識,請移步Unity3d的官方文檔

編程實踐

作業要求

UI 效果製作(你僅需要實現以下效果之一)

進入 NGUI 官方網站,使用 UGUI 實現以下效果

  • Inventory 揹包系統
  • Quest Log 公告牌
  • Scroll View 選擇板
    以上例子需要使用 Unity web player, 僅支持以下操作系統與瀏覽器,參見官方下載
    Windows 版 IE11
    Mac OS X 10.7 Safari
    出現界面需要等待較長時間,打開頁面讓它慢慢加載

我選擇的題目是實現Quest Log 公告牌。

基本配置

按官方手冊,EventSystem 在一個場景中 有且僅能有一個,它將遊戲操縱桿、鍵盤、鼠標、觸摸屏、觸摸屏與 UI 對象交互事件,如 Click,MouseMOver,DragEnter 等等,傳遞給遊戲對象對應的行爲組件。

菜單通常由一個 Canvas 和 若干 Panel 組成的,所有 UI 元素組成一個樹形結構。

在canvas下新建一個滾動視圖scoll view。然後在Scroll View -> Viewport -> Content下添加垂直列表組件vertical layout group和Button1,2,3以及對應的Text1,2,3用於顯示公告的按鈕和文字。
在這裏插入圖片描述
在button和text上分別設置要顯示的文字內容,文字格式等等。
在這裏插入圖片描述
之後可以直接通過UGUI對公告牌的大小位置以及其他屬性進行設置。調整垂直列表中的間距還有自適應寬高等的屬性。
在這裏插入圖片描述

最後我們可以對公告牌和整個canvas分別添加背景圖片,這裏我就是在網上找的圖片素材,然後添加到asset的img文件夾下即可,唯一要注意的是,要將這些背景圖片的Texture Type變爲Sprite(2D and UI),才能夠添加成功。

在這裏插入圖片描述

代碼分析

這一次的作業因爲很多部分都是用UGUI直接可以操作的,所以代碼比較簡單,主要就是實現公告文字的隱藏和展開。

這裏我們使用了C#的協程接口IEnumerator,它允許你爲自己的集合類型編寫枚舉器,IEnumerator迭代器和yield關鍵字需要配合使用。Unity協程長的類似於線程,但卻不是線程。因爲協程仍然是在主線程中執行,且在使用時不用考慮同步與鎖的問題。協程只是控制代碼等到特定的時機後再執行後續步驟。我們可以寫一段順序的代碼,標明哪裏需要暫停,然後在下一幀或者一段時間後,系統會繼續執行這段代碼。通過每幀來改變文本的角度和文本的高度,來實現隱藏和展開的效果。

完整代碼如下:

public class Board : MonoBehaviour {
    // 分別對應按鈕和文本內容
    private Button button;
    public Text text;

    private float height; // 公告文本的高度
    private int frame = 20;    // 公告內容變化幀數

    void Start()
    {
        // 獲取button,添加監聽事件
        button = this.gameObject.GetComponent<Button>();
        button.onClick.AddListener(showOrHide);
        // 並獲取公告文本的高度,以便還原
        height = text.rectTransform.sizeDelta.y;
    }

    void showOrHide()
    {
        // 判斷文本是選擇隱藏還是顯示
        if (text.gameObject.activeSelf)
            StartCoroutine(hide());
        else
            StartCoroutine(show());
    }

    IEnumerator hide()
    {
        float h = height;
        for (int i = 0; i < frame; i++)
        {
            h -= height / frame;
            text.rectTransform.sizeDelta = new Vector2(text.rectTransform.sizeDelta.x, h);
            // 在這停頓,下一幀再執行
            yield return null;
        }
        text.gameObject.SetActive(false);
        // 禁用文本
    }

    IEnumerator show()
    {
        float h = 0;
        text.gameObject.SetActive(true);
        // 激活文本

        for (int i = 0; i < frame; i++)
        {
            h += height / frame;            
            text.rectTransform.sizeDelta = new Vector2(text.rectTransform.sizeDelta.x, h);
            // 在這停頓,下一幀再執行
            yield return null;
        }

    }
}

完成代碼後,我們需要把它掛載到我們的每一個button之上,並把每個button對應的text拖到相應的欄目裏面即可。

遊戲界面效果

隱藏文本:
在這裏插入圖片描述
展開文本:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章