【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)的用法相似,可直接将其添加到场景或层次视图中,并通过检视器修改其参数:

例如,向场景中添加一个Text,并通过检视器修改它的字体大小为24,颜色为红色:
下面是在层次视图中看到的结果:

也许下面的另一个场景截图更能让你明白它的用法:
除了可将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) 时就会看到下面的菜单:

由于 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);
}

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);
}

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();
}

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");
}
}
}
}
【Unity】8.1 Unity内置的UI控件的更多相关文章
- WebBrowser是IE内置的浏览器控件
WebBrowser是IE内置的浏览器控件.WebBrowser是IE内置的浏览器控件.WebBrowser是IE内置的浏览器控件.重要的事情说三遍,原因是一开始使用的时候就在这踩了坑. WebBro ...
- C#程序员整理的Unity 3D笔记(十五):Unity 3D UI控件至尊–NGUI
目前,UGUI问世不过半年(其随着Unity 4.6发布问世),而市面上商用的产品,UI控件的至尊为NGUI:影响力和广度(可搜索公司招聘Unity 3D,常常能看到对NGUI关键词). NGUI虽然 ...
- 【Unity/Kinect】Kinect实现UI控件的点击
用体感来实现UI控件的点击,如点击按钮. 做法:用一个图片表示左手手掌,图片位置追踪左手手掌移动,当手掌位于UI控件的矩形内时,握拳表示点击该控件. using UnityEngine; using ...
- 线程池内的异步线程创建UI控件,造成UI线程卡死无响应的问题分析
winform应用在使用一段时间后,切换到其他系统或者打开word.excel文档,再切换回winform应用时,系统有时出现不响应的现象.有时在锁屏后恢复桌面及应用时也发生此问题. 经微软支持确认, ...
- 优化UI控件 【译】
翻译自:https://unity3d.com/cn/learn/tutorials/topics/best-practices/optimizing-ui-controls?playlist=300 ...
- UI控件Telerik UI for WinForms发布R1 2019|附下载
Telerik UI for WinForms拥有适用Windows Forms的110多个令人惊叹的UI控件.所有的UI for WinForms控件都具有完整的主题支持,可以轻松地帮助开发人员在桌 ...
- Atitit.swt 线程调用ui控件的方法
Atitit.swt 线程调用ui控件的方法 1 SwingUtilities.invokeLater1 2 display.asyncExec方法1 3 display.timerExec(500 ...
- unity4.6 Beta版 UI控件之Button
近期需求,须要用到4.6版本号uGui了,所以抽时间来学习学习,就UI控件在Unity工具里创建预设这块来说相比較于NGUI,我认为是没有什么太大的差别的. 比方:Canvas--Camera . T ...
- Android4.0 -- UI控件之 Menu 菜单的的使用(三)
上一讲 [Android 开发]:UI控件之 Menu 菜单的的使用(二) 我们讲解了创建上下文菜单的第一种使用方式:Creating a floating context menu [创建悬浮的上下 ...
随机推荐
- 【Linux】命令写在文件中并调用awk -f
我们在使用awk命令的时候,有时候命令特别长,在终端写出来格式太乱,难以阅读,以下是一个将命令写在文件中,并使用awk调用的具体案例 1.现在有文件file3.txt,内容如下: 2.ak2.awk脚 ...
- X-Forwarded-For 会少记录一次代理服务器的IP
X-Forwarded-For是一个Http请求头中的项目. 当一个请求经过代理时,X-Forwarded-For将被记录下来,规则如下: 假设用户U,通过代理服务器A,请求到服务器S, 那么X-Fo ...
- JS修改当前控件样式&为控件追加事件
先搁这吧,今天太晚了,以后再加注释和修整吧.不幸搜到的朋友就别看了 <%@ Page Language="vb" AutoEventWireup="false&qu ...
- MySQL Replication主从复制环境下修改主库IP
因为调整服务器子网, 数据库服务器的IP地址需要修改. 这个过程中, 需要确保的就是从库在断开主库后, 能从正确的位置再次启动. 具体的操作步骤如下 1) 需要获取的前提信息: 主库的新IP, 这在启 ...
- Libevent例子(二)
服务端 #include<netinet/in.h> #include<stdio.h> #include<string.h> #include<event. ...
- 开源分布式搜索平台ELK(Elasticsearch+Logstash+Kibana)入门学习资源索引
from: http://www.w3c.com.cn/%E5%BC%80%E6%BA%90%E5%88%86%E5%B8%83%E5%BC%8F%E6%90%9C%E7%B4%A2%E5%B9%B ...
- 阿里云ecs配置辅助网卡绑定公网ip地址
EIP直通车 前置条件:1.大家的实例是从经典迁移到VPC里面的,上古时期,经典实例大家购买实例的时候都是买了带宽的.而这种带宽一般情况下都是包年包月的,而且这种绑定在实例上的IP,我们把它叫做公网I ...
- KVM虚拟机的创建、管理与迁移
[日期:2012-06-01] KVM虚拟机管理 一.环境 role hostname ip OS kvm_server target ...
- 【DeepLearning】用于几何匹配的卷积神经网络体系结构
[论文标题]Convolutional neural network architecture for geometric matching (2017CVPR) [论文作者]Ignacio Rocc ...
- 【LeetCode】208. Implement Trie (Prefix Tree)
Implement Trie (Prefix Tree) Implement a trie with insert, search, and startsWith methods. Note:You ...