zoukankan      html  css  js  c++  java
  • 【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");
                }
            }
        }
    }
  • 相关阅读:
    进程和线程
    进程通信、同步与调度
    文件和文件系统
    【nexys3】【verilog】小设计——拆弹游戏
    Qt4开发环境搭建(Qt4.8.7+mingw4.8.2+Qt Creator4.2.0)
    GPL和LGPL
    【rpi】使用putty远程连接rpi(ssh)
    mysql 命令 小结
    安装mysql zip 安装包 Navicat连接
    python虚拟环境 virtualenv工具
  • 原文地址:https://www.cnblogs.com/rainmj/p/5437392.html
Copyright © 2011-2022 走看看