【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");
            }
        }
    }
}
原文地址:https://www.cnblogs.com/rainmj/p/5437392.html