【Unity】8.1 Unity內置的UI控件


分類:Unity、C#、VS2015

創建日期:2016-04-27

一、簡介

Unity 5.x內置了—套完整的GUI系統,提供了從布局、控件到皮膚的—整套GUI解決方案,因此可直接利用它做出各種風格和樣式的GUI界面,並且擴展性很強(程序員可以基於已有的控件創建出適合自己需求的控件)。

有兩種使用GUI的辦法,一種是直接將UI添加到層次視圖或者場景視圖中,然后通過GUI腳本去控制它;另一種是直接通過GUI腳本去創建。

二、直接添加UI控件到場景中

下圖是Unity 5.3.4內置的UI控件,這些UI控件的用法和其他游戲對象(GameObject)的用法相似,可直接將其添加到場景或層次視圖中,並通過檢視器修改其參數:

image

例如,向場景中添加一個Text,並通過檢視器修改它的字體大小為24,顏色為紅色:

image

下面是在層次視圖中看到的結果:

image

也許下面的另一個場景截圖更能讓你明白它的用法:

image

除了可將UI直接添加到場景中並在OnGUI()函數中通過腳本去控制它以外,還可以在OnGUI()函數中通過腳本去控制。

再次提醒注意:

(1)GUI代碼需要在 OnGUI() 函數中控制,不能放在 Update() 函數中。

(2)GUI中的坐標位置與Input.mousePosiotion的鼠標位置不同。在Unity GUI中,屏幕坐標系以“左上角”為原點(0,0),“右下角”為(screen.Wdth,screen.Height)。其中screen.Width為屏幕寬度,screen.Height為屏幕高度,以像素為單位。而對於Input.mousePosition來說,它的屏幕“左下角”為原點(0,0),屏幕“右上角”為(Screen.Width,Screen.Height)。

三、OnGUI()函數

UnityGUI 控件使用一種稱為 OnGUI() 的特殊函數。只要啟用了包含的腳本,每幀都會自動調用OnGUI() 函數。

GUI 控件本身結構很簡單。例如,下面是“等級加載器”的示例代碼:

using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour
{
    void OnGUI ()
    {
        // 制作背景盒
        GUI.Box(new Rect(10,10,100,90), "Loader Menu");
        // 制作第一個按鈕。按下這個按鈕將執行 Application.Loadlevel (1)
        if(GUI.Button(new Rect(20,40,80,20), "Level 1"))
        {
            Application.LoadLevel(1);
        }
        // 制作第二個按鈕。
        if(GUI.Button(new Rect(20,70,80,20), "Level 2"))
        {
            Application.LoadLevel(2);
        }
    }
}

此示例是一個完整的功能性等級加載器。如果你將此腳本拖到游戲對象 (GameObject) 上,則進入播放模式 (Play Mode) 時就會看到下面的菜單:

image

由於 OnGUI() 代碼在每一幀都會被調用,因此你不需要明確創建或銷毀 GUI 控件。如果你需要在特定的時間顯示控件,可使用任何一種腳本邏輯來操作,例如:

void OnGUI ()
{
    if (Time.time % 2 < 1)
    {
        if (GUI.Button (new Rect (10,10,200,20), "Meet the flashing button"))
    {
        print ("You clicked me!");
    }
}

此處,GUI.Button() 每隔一秒調用一次,因此此按鈕會出現然后消失。因此,如果按這樣的方式來實現,只有在按鈕可見時用戶才能單擊它。

聲明 GUI 控件時必需有三條關鍵信息:

控件類型(顯示的位置,顯示的內容)

其中:

控件類型:是通過調用 UnityGUI 類或 GUILayout 類中的一個函數來聲明的。

位置:這是 GUI 控件函數中的第一個參數。示例代碼中的Rect() 定義了四種屬性:最左端位置、最頂端位置、控件總寬度和控件總高度。所有這些值都是整數(與像素值對應)。

所有 UnityGUI 控件都在屏幕空間 (Screen Space)中運行,左上角為(0,0),右下角為最大坐標值(Screen.width,Screen.height)。

再看一個例子:Rect(10, 20, 300, 100) 定義矩形 (Rectangle),該矩形始於坐標:10,20,結束於坐標(310,120),即:(10+300,20+100)。

使用Screen.width 和 Screen.height 屬性可獲取屏幕空間的總尺寸。例如:

void OnGUI()
{
    GUI.Box (new Rect (0,0,100,50), "Top-left");
    GUI.Box (new Rect (Screen.width - 100,0,100,50), "Top-right");
    GUI.Box (new Rect (0,Screen.height - 50,100,50), "Bottom-left");
    GUI.Box (new Rect (Screen.width - 100,Screen.height - 50,100,50), "Bottom-right");
}

這段C#代碼的效果是:四個按鈕分別顯示在屏幕的四個角。

用於 GUI 控件的第二個參數是用控件顯示的實際內容,它既可以是文本,也可以是圖像。如果希望顯示圖像,先聲明一個二維紋理 (Texture2D)類型的公共變量,並將變量名稱作為內容參數即可:

public Texture2D controlTexture;
void OnGUI ()
{
    GUI.Label (new Rect (0,0,100,50), controlTexture);
}

下面是更接近真實世界場景的代碼示例:

using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour
{
    public Texture2D icon;
    void OnGUI ()
    {
        if (GUI.Button (new Rect (10,10, 100, 50), icon))
        {
            print ("you clicked the icon");
        }
        if (GUI.Button (new Rect (10,70, 100, 20), "This is text"))
        {
            print ("you clicked the text button");
        }
    }
}

下面的C#代碼演示了如何同時顯示圖像和文本:

public Texture2D icon;
void OnGUI ()
{
    GUI.Box (new Rect (10,10,100,50), new GUIContent("This is text", icon));
}

下面的C#代碼演示了如何同時顯示文本和工具提示(Tooltip)。當鼠標在控件上方懸停時,Tooltip就會顯示在適當的位置:

void OnGUI () 
{
    // 該行向 GUI 工具提示輸入“This is the tooltip”
    GUI.Button (new Rect (10,10,100,20), new GUIContent ("Click me", "This is the tooltip"));
    // 該行讀取並顯示 GUI 工具提示的內容
    GUI.Label (new Rect (10,40,100,20), GUI.tooltip);
}

下面的C#代碼演示了如何同時顯示圖像、文本和工具提示(Tooltip):

public Texture2D icon;
void OnGUI ()
{
    GUI.Button (new Rect (10,10,100,20), new GUIContent ("Click me", icon, "This is the tooltip"));
  GUI.Label (new Rect (10,40,100,20), GUI.tooltip);
}

當鼠標在控件上方懸停時,Tooltip的內容“This is the tooltip”就會顯示出來。

四、通過腳本創建UI控件

這里僅介紹如何通過腳本去創建和使用UI控件。

1、Label

Label控件適合用來顯示文本信息或者圖片,它不會響應鼠標或鍵盤消息。

void OnGUI ()

{

GUI.Label (new Rect (25, 25, 100, 30), "這是Label");

}

2、Box

該控件可用來繪制帶有邊框背景的立方體或長方體文字或圖片。

GUI.Box(new Rect(0,0,Screen.width*0.5,Screen.height*0.5),"Hello");

3、Button、RepeatButton

該控件用來繪制晌應單擊事件的按鈕。

當有按鈕單擊事件發生時,Button函數返回true,否則返回false。因此,按鈕的事件處理腳本需要寫在控件代碼if語句條件為true的代碼區域中。

using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour
{
    public Texture2D btnTexture;
    void OnGUI()
    {
        if(GUI.Button(new Rect(10,10,50,50),btnTexture))
        {
            Debug.Log("你單擊了圖片按鈕");
        }
        if (GUI.Button(new Rect(10, 10, 50, 50), "請點擊我!"))
        {
            Debug.Log("你單擊了文字按鈕");
        }
    }
}

Button控件在每次單擊事件中只響應一次,如果想處理鼠標左鍵長按的事件,可以使用RepeatButton控件。

RepeatButton會在左鍵按下期間一直返回true。

4、TextField、PasswordField、TextArea

TextField:單行文本框

TextArea:多行文本框

PasswordField:密碼輸入框

游戲中經常需要用到信息輸入的窗口,比如聊天窗、用戶信息的輸入等,這些情況可以使用TextField控件:

private string textFieldString = "text field";
void OnGUI()
{
    textFieldString = GUI.TextField(new Rect(25, 25, 100, 30), textFieldString);
}

TextArea控件與TextField的用法類似,區別就是TextField是單行的,TextArea可以編輯多行文字:

private string textAreaString = "text area";
void OnGUI()
{
    textAreaString = GUI.TextArea(new Rect(25, 25, 100, 30), textAreaString);
}

PasswordField控件用於繪制密碼輸入框,經常用於用戶登錄界面中:

public string pwd="12345";
void OnGUI()
{
    pwd = GUI.PasswordField(new Rect(10, 10, 200, 20), pwd, '*');
}

5、Toggle

Toogle:復選框。相當於CheckBox。

Toogle控件一般用作開關,每次單擊Toogle都會在“開”和“關”之間切換。例如:

private bool toggleBool = true;
void OnGUI()
{
    toggleBool = GUI.Toggle(new Rect(25, 25, 100, 30), toggleBool, "Toggle");
    if(toggleBool == true){//……}
}

也可以顯示一個圖片開關,其用法和Label類似。

6、ToolBar、SelectionGrid

ToolBar:單選按鈕工具欄。相當於在工具欄中顯示一組RadioButton。

SelectionGrid:多排工具欄 (Toolbar)。它可以自動決定柵格中顯示的列數和行數。仍然是一次僅可激活一個“按鈕”(Button)。

ToolBar控件適用於繪制一組按鈕,在這些按鈕中同時只激活—個,可以利用它來制作選項卡式的工具欄:

private int toolbarInt = 0;
private string[] toolbarStrings = { "Toolbar1", "Toolbar2", "Toolbar3" };
void OnGUI()
{
    toolbarInt = GUI.Toolbar(new Rect(25, 25, 250, 30), toolbarInt, toolbarStrings);
}
image

SelectionGrid通過一個整數可跟蹤“柵格選擇”(SelectionGrid) 中激活的“按鈕”(Button)。必須提供該整數作為此函數的參數和返回值。提供的內容數組中的元素數目將決定“柵格選擇”(SelectionGrid) 中顯示的“按鈕” (Button) 的數目:

private int selectionGridInt = 0;
private string[] selectionStrings = { "Grid 1", "Grid 2", "Grid 3", "Grid 4" };
void OnGUI()
{
    selectionGridInt = GUI.SelectionGrid(new Rect(25, 25, 300, 60), selectionGridInt, selectionStrings, 2);
}

image

7、HorizontalSlider、VertialSlider

滑動條(Slider)一般用於音量調整、進度顯示、數值調整的GUI界面中。

“滑動條”(Slider) 的當前位置以浮點數形式存儲。要顯示滑動條的當前位置,需要提供 該浮點數作為函數的參數。另有兩個值用於確定最小值和最大值。如果希望滑動條鈕是可調的,則將滑動條值浮點數指定為“滑動條"(Slider) 函數的返回值。

在Unity中,Slider控件分為水平和垂直2種布局方式,對應的函數為HorizontalSlider和VertialSlider。

下面是HorizontalSlider的基本用法:

private float hSliderValue = 0.0f;
void OnGUI()
{
   hSliderValue = GUI.HorizontalSlider(new Rect(25, 25, 100, 30), hSliderValue, 0.0f, 10.0f);
}

下面是VertialSlider的基本用法:

private float vSliderValue = 0.0f;
void OnGUI()
{
    vSliderValue = GUI.VerticalSlider(new Rect(25, 25, 100, 30), vSliderValue, 10.0f, 0.0f);
}

8、HorizontalScrollbar、VertialScrollbar

滾動條(ScrollBar)常用於頁面區域的滾動,例如文檔瀏覽。在Unity中,ScrollBar控件分為水平和垂直2種,對應的GUI函數為HorizontalScrollbar和VertialScrollbar。

水平滾動條(HorizontalScrollbar) 的執行與水平滑動條(Horizontal Slider) 相同,但有一個例外之處:另有一個參數控制“滾動條”(Scrollbar) 鈕自身的寬度。

private float hScrollbarValue;
void OnGUI()
{
    hScrollbarValue = GUI.HorizontalScrollbar(new Rect(25, 25, 100, 30), hScrollbarValue, 1.0f, 0.0f, 10.0f);
}

垂直滾動條的用法與其類似,這里就不再舉例了。

9、ScrollView

ScrollView用來在GUI界面中繪制一個滾動視圖區域,並旦可以通過滾動條來控制要顯示的區域內容。

ScrollView通過成對調用BeginScrollView和EndScrollView來完成繪制。在這2個函數之間的GUI代碼會繪制在滾動視圖內部區域中。

private Vector2 scrollViewVector = Vector2.zero;
private string innerText = "I am inside the ScrollView";
void OnGUI()
{
    // 開始“滾動視圖”(ScrollView)
    scrollViewVector = GUI.BeginScrollView(new Rect(25, 25, 100, 100), scrollViewVector, new Rect(0, 0, 400, 400));

    // 向“滾動視圖”(ScrollView) 輸入內容
    innerText = GUI.TextArea(new Rect(0, 0, 400, 400), innerText);

    // 結束“滾動視圖”(ScrollView)
    GUI.EndScrollView();
}
image

10、Window

可以將Window看作是控件的容器,即把其他控件都繪制在這個窗口中,這樣可以方便地調整窗口內所有控件的位置,以及顯示隱藏。

Window函數會調用另外一個函數來進行繪制控件的工作。在繪制控件函數中,控件的位置為窗口自身坐標系下的位置,如果控件位置超出了窗口的區域,將不會顯示。

如果想讓窗口可拖動,在繪制函數中調用DragWindow函數可以設置窗口的拖動位置。

private Rect windowRect = new Rect(20, 20, 220, 100);
void OnGUI()
{
    windowRect = GUI.Window(0, windowRect, WindowFunction, "My Window");
}

void WindowFunction(int windowID)
{
    // 在此處繪制窗口內的所有控件
    GUI.Button(new Rect(60,50,100,20),"OK");
    ……
    GUI.DrawWindow(new Rect(0,0,120,20)); //讓窗口可以通過標題欄拖動位置
}

三、GUI.changed

要檢測用戶是否對 GUI 進行過操作(如點擊“按鈕”(Button)、拖動滑動條等等),可通過腳本讀取 GUI.changed 的值。如果用戶進行過操作則該值為 true,通過它可以很容易確定用戶的輸入。

對於“工具欄”(Toolbar) 可能會出現這種情況,即你想根據“工具欄”(Toolbar) 中點擊“按鈕”(Button) 時都分配該值,而不是僅在點擊其中一個“按鈕”(Button) 時進行分配,此時可以用下面的代碼實現:

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {

    private int selectedToolbar = 0;
    private string[] toolbarStrings = {"One", "Two"};

    void OnGUI () {
        // 確定到此幀時哪個按鈕處於激活狀態以及其是否被點擊過
        selectedToolbar = GUI.Toolbar (new Rect (50, 10, Screen.width - 100, 30), selectedToolbar, toolbarStrings);

        // 如果用戶在此幀點擊了一個按鈕,則處理其輸入
        if (GUI.changed)
        {
            Debug.Log("The toolbar was clicked");

            if (0 == selectedToolbar)
            {
                Debug.Log("First button was clicked");
            }
            else
            {
                Debug.Log("Second button was clicked");
            }
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM