unity3d 创建gui

2013-12-11 14:48:34 zuoyamin 阅读数 35339
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

       Unity为大家提供了一套很完整的图形化界面引擎,包括窗口、文本框、拖动条等。下面将为大家介绍主要的基本控件。


一、Label控件

       Label控件(标签控件)以文本的形式来显示一串字符串信息,该控件不仅可以输入字符串信息,还可以输入贴图。

参数:
position : Rect ——标签在屏幕上的矩形位置,(起点x坐标,起点y坐标,标签宽度,标签高度)。
text : String ——在标签上显示的文本内容。
image : Texture ——在标签上显示的纹理。
content : GUIContent ——在标签上显示的文本、图片和信息提示。
style : GUIStyle ——使用的样式,如果不使用,那么标签的样式使用的就是当前的GUISkin皮肤
描述:
在屏幕上创建一个文本或纹理的标签。

标签没用用户交互,不捕捉鼠标点击,如果想创建响应用户输入的控件,可以使用Box控件。

案例:绘制一个“Hello World!”标签和一个图片标签
       首先,在Project视图中的一个文件夹上右击→Create→C# Script,然后为其重命名为Label。在这里需要注意的是脚本文件的名称必须和脚本中pulic class XXX :MonoBehaviour一样,不然会出错的。双击打开脚本编写器,接着就是编写脚本,编写的内容如下:
using UnityEngine;
using System.Collections;

public class Label : MonoBehaviour {

	public Texture img;//图片/
	
	void OnGUI()
	{
		GUI.Label(new Rect(10,10,200,20),"Hello World!");
		GUI.Label(new Rect(10,50,200,200),img);
	}
}
        在这个脚本中只用一个OnGUI方法,该方法为绘制界面的方法,所有GUI的绘制都需要在这个方法中实现。
        另外,脚本必须绑定到对象上才会执行自身的生命周期。绑定的方法很简单,就是在Project视图中将该脚本文件拖拽到Hierarchy视图中的一个对象上即可。在这里我们将Label.cs脚本绑定到Main Camera对象上。
       接着是图片变量的赋值,首先只用公有变量才能从Project中拖拽赋值或者手动输入赋值,即前面有public关键字。

游戏视图:


二、Button控件和RepeatButton控件

       Button控件(按钮控件)用来进行用户的行为判断,例如:确认,取消,退出等。按钮有3中状态:未点击,点击,点击后,在一般情况下,我们只用到未点击和点击这2种情况。

Parameters(参数):
position : Rect ——按钮在屏幕上的矩形位置,(起点x坐标,起点y坐标,按钮宽度,按钮高度
text : String ——按钮上显示的文本内容
image : Texture ——按钮上显示的图片纹理
content : GUIContent ——按钮的文本,图片和提示。
style : GUIStyle ——按钮使用的样式,如果不使用,则按钮的样式使用的就是当前的GUISkin皮肤


Returns(返回):
布尔值——当该按钮被点击时返回true

Description(描述):
创建一个单次按下按钮,当用户点击按钮时立即触发事件。

RepeatButton(连续按钮)用于持续按下时触发事件的按钮,普通的Button按钮适用与单次按下。

参数与普通的Button没什么大的区别。

Returns返回值:
布尔值——当用户按下该按钮时返回true。

描述:
创建一个按钮,只要用户按住不放,将一直被激活。
从按下按钮到释放按钮的时间内重复触发其Click事件,也就是说他将连续不停的发送点击事件。

案例:创建3个按钮,分别为普通文本按钮,普通图片按钮,连续按钮。再创建了3个标签,第一个标签用于显示用户按下的按钮是哪一个,第二个标签是用来显示普通图片按钮按下后,绘制一个图片出来,第三个标签用来记录连续按钮按下的时间。
using UnityEngine;
using System.Collections;

public class Button : MonoBehaviour {

	public Texture img;//公有变量图片/
	private Texture img0;
	private string info;//显示的信息/
	private int frameTime;//记录按下的时间/
	
	void Start()
	{
		//初始化/
		info = "请您点击按钮";
		frameTime = 0;
	}
	
	void OnGUI()
	{
		//标签/
		GUI.Label(new Rect(50,10,200,20),info);		
		//普通按钮,点击后显示Hello World
		if(GUI.Button(new Rect(50,250,200,20),"Hello World"))
		{
			info = "Hello World";
		}
		//标签/
		GUI.Label(new Rect(280,10,200,200),img0);
		//图片按钮,点击后显示图片/
		if(GUI.Button(new Rect(280,250,200,200),img))
		{
			img0 = img;
			info = "您点击了图片按钮";
		}
		//标签/
		GUI.Label(new Rect(500,10,200,20),"持续按下的时间:" + frameTime);
		//连续按钮,点击后显示按下的时间/
		if(GUI.RepeatButton(new Rect(500,250,200,20),"持续按下"))
		{
			frameTime ++ ;
			info = "您按下了连续按钮";
		}		
		//每当鼠标按下时将frameTime重置,一遍进行下次记录/
		if(Input.GetMouseButtonDown(0))
		{
			frameTime = 0;
		}
	}
}
在这里依旧需要将脚本绑定Main Camera上,并且将需要赋值的公有变量进行赋值,在Label控件中我已经介绍了,这里就不废话了~

游戏视图:







———————————————
参考文献:
《Unity3D 游戏开发》宣玉松
 Unity Script Reference

2013-12-21 22:25:14 aisajiajiao 阅读数 46839
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

原文地址

在这篇文章中我将给读者介绍Unity中的图形用户界面(GUI)编程.Unity有一个非常强大的GUI脚本API.它允许你使用脚本快速创建简单的菜单和GUI.

简介

Unity提供了使用脚本创建GUI界面的能力.在写这篇文章的时候,Unity还没有提供一套原生的可视化GUI开发工具,尽管你可能会在Unity Asset商店找到一些使用某种形式的图形化脚本编程编写GUI的工具.Autodesk Scaleform也提供了一个可以单独购买并整合进Unity的插件但这超出了这篇文章的范围.如果你对Scaleform插件的unity版本感兴趣,我推荐你看看Scaleform Unity Plugin.

Unity提供了两个主要的类来创建GUI.GUI类用于创建手动放置的GUI控件.GUILayout类用于创建自动放置的GUI控件.这两个类之间的区别将在文章后面搞清楚.

Unity也提供了GUISkin资源(asset翻译成套件?).它可以被应用于给你的GUI控件提供一种通用的的"外观和感觉".一个GUISkin只是GUIStyle对象的集合.每个GUIStyle对象定义了单个GUI控件的样式,比如按钮,标签或者文本域.

GUiText组件可被用于渲染单个的文本元素,GUITexture组件可以被用于渲染2D材质到屏幕.GUIText和GUITexture都适用于为你的游戏绘制GUI元素(就像HUD),但这些组件不适用于在游戏中绘制菜单.对于游戏中的菜单(像等级选择和选项设置页面)你应该使用GUI和GUILayout类.

这些不同的类,资源(Asset)和组件每一个本文中都会阐述

创建菜单

首先我讲述一下如何在使用GUI和GUILayout在Unity中创建菜单.我也会向你展示如何使用GUISkin和GUIStyle来自定义GUI控件的外观

OnGUI回调函数

GUI的渲染是通过创建脚本并定义OnGUI函数来执行的.所有的GUI渲染都应该在该函数中执行或者在一个被OnGUI调用的函数中执行

ButtonDemo.js

function OnGUI()
{
	var buttonWidth = 100;
	var buttonHeight = 50;

	var buttonX = (Screen.width - buttonWidth) / 2.0f;
	var buttonY = (Screen.height - buttonHeight) / 2.0f;
	
	//在屏幕中间绘制一个button组件
	if(GUI.Button(Rect(buttonX,buttonY,buttonWidth,buttonHeight),"Press Me!"))
	{
		//在调试控制台打印一些文字
		Debug.Log("Thanks!");
	}
}
脚本ButtonDemo.js将会在屏幕中间绘制一个按钮,松开按钮文字"Thanks!"就会被打印到调试控制台.

GUIContent

大多数通用控件比如按钮和标签允许你指定控件上该呈现在控件上的的文本或者材质.如果你想在一个控件上指定文本与材质,那必须使用GUIContent结构.

CUIContent结构有几个构造函数允许你创建一个带有文本,材质和tooltip的CUIContent对象.

下面的例子扩展了之前的例子,但在这个例子中按钮的内容由GUIContent结构指定.

ButtonDemo.js

#pragma strict
var texture:Texture;
var text:String = "hello text";
var toolTip:String = "hello toolTip";

function OnGUI()
{
	var buttonWidth = 100;
	var buttonHeight = 50;
	
	var buttonX = (Screen.width - buttonWidth) / 2.0f;
	var buttonY = (Screen.height - buttonHeight) / 2.0f;
	
	//在屏幕中心绘制一个带有文本和图像的按钮
	if(GUI.Button(Rect(buttonX,buttonY,buttonWidth,buttonHeight),GUIContent(text,texture,toolTip)))
	{
		//在调试控制台打印一些文字
		Debug.Log("Thanks!");
	}
}
改进后的ButtonDemo.js脚本将会在屏幕上显示一个文本与材质.材质,文本和tooltip参数可以在检视器(inspector)中指定.

ButtonDemo.js脚本会产生如下结果.

放置控件

使用GUI类你必须手动的摆放屏幕上的控件.控件使用GUI静态函数的position参数来摆放.为了在屏幕上摆放控件,必须将一个Rect结构作为第一个参数传递给GUI控件函数.Rect结构的为控件定义了X,Y,Width,Height属性.X,Y,Width和Height单位都是像素.

Screen.width和Screen.height属性可以被用于检视当前屏幕的范围.

脚本ScreenDimension.js可以被用于渲染上面的截图.

ScreenDimensions.js

function OnGUI()
{
	var width = Screen.width;
	var height = Screen.height;
	
	GUI.Label(Rect(0,0,100,20),"Top Left");
	GUI.Label(Rect(width - 100,0,100,20),"Top Right");
	GUI.Label(Rect(0,height - 20,100,20),"Bottom Left");
	GUI.Label(Rect(width - 100,height - 20,100,20),"Bottom Right");
}
ScreenDimension.js脚本将绘制4个标签.每个标签都使用Screen.width和Screen.height属性来决定其屏幕位置并对齐到屏幕角落里(测量单位为像素)

GUI类

GUI类是Unity用于将控件渲染到屏幕上的主要类.GUI类使用手动摆放来决定屏幕上控件的位置.这意味着在渲染控件时你必须显式的指定控件在屏幕上的位置.使用这种方法手动摆放控件需要多做些工作但他可以让你精确地控制屏幕上的控件位置.如果你不想手动的指定GUI控件的位置,那你应该使用GUILayout类.我们后面再详细阐述GUILayout.

GUI控件

在下面的章节中,我将介绍在使用GUI和GUILayout时可利用的不同控件这些类提供的默认控件是box,button,label,window,texture,scroll bars,sliders,textfield,textarea,toggle和toolbar

GUI.BUTTON

可能你最常用的控件之一就是按钮了.你可以使用GUI.Button()静态函数来创建一个按钮.这个函数用于将按钮渲染到屏幕上,当松开按钮时函数返回true.

这里值得一说的是GUI.Button函数只会在鼠标在按钮上按下并且在按钮上松开时才返回true,如果用户按下按钮移动鼠标在按钮外面释放鼠标,则函数不会返回TRUE,同样的如果用户按下了鼠标之后将光标移动到按钮上然后释放鼠标该函数也不会返回TRUE.要使该函数返回true,鼠标必须在按钮上按下并释放.

以下代码可用于使用按钮创建一个简单的等级选择屏幕(假定你在Build Settings对话框中有多个场景文件要设置)

LevelSelect.js

function OnGUI()
{
	var groundWidth = 120;
	var groundHeight = 150;
	
	var screenWidth = Screen.width;
	var screenHeight = Screen.height;
	
	var groupx = (screenWidth - groundWidth) / 2;
	var groupy = (screenHeight - groundHeight) / 2;
	
	GUI.BeginGroup(Rect(groupx,groupy,groundWidth,groundHeight));
	GUI.Box(Rect(0,0,groundWidth,groundHeight),"Level Select");
	
	if(GUI.Button(Rect(10,30,100,30),"Level 1"))
	{
		Application.LoadLevel(1);
	}
	if(GUI.Button(Rect(10,70,100,30),"Level 2"))
	{
		Application.LoadLevel(2);
	}
	if(GUI.Button(Rect(10,110,100,30),"Level 3"))
	{
		Application.LoadLevel(3);
	}
	
	GUI.EndGroup();
}
将脚本添加到空的场景中会产生如下结果:

你也许会想看看Unity脚本参考里的GUI.ToggleGUI.RepeatButton,这些与GUI.Button控件类似但略有不同的功能.

GUI.Label

GUI.Label()静态函数用于绘制一个标签.标签通常实在屏幕上指定位置绘制的文字.标签控件最常用的是在菜单屏幕中指定选项名称(比如文本框和文本域).

标签可包含文字,材质或者两者兼有(使用之前讲过的GUIContent结构)

下面的例子在屏幕上显示绘制了两个选项.选项名称和滑块的值使用标签呈现

OptionsMenu.js

#pragma strict

private var masterVolume:float = 1.0;
private var sfxVolume:float = 1.0;

function OnGUI()
{
	var groupWidth = 380;
	var groupHeight = 110;
	
	var screenWidth = Screen.width;
	var screenHeight = Screen.height;
	
	var groupX = (screenWidth - groupWidth) / 2;
	var groupY = (screenHeight - groupHeight) / 2;
	
	GUI.BeginGroup(Rect(groupX,groupY,groupWidth,groupHeight));
	GUI.Box(Rect(0,0,groupWidth,groupHeight),"Audio Settings");
	
	GUI.Label(Rect(10,30,100,30),"Master Volume");
	masterVolume = GUI.HorizontalSlider(Rect(120,35,200,30),masterVolume,0.0,1.0);
	GUI.Label(Rect(330,30,50,30),"(" + masterVolume.ToString("f2") + ")");
	
	GUI.Label(Rect(10,70,100,30),"Effect Volume");
	sfxVolume = GUI.HorizontalSlider(Rect(120,75,200,30),sfxVolume,0.0,1.0);
	GUI.Label(Rect(330,70,50,30),"(" + sfxVolume.ToString("f2") + ")");
	
	GUI.EndGroup();
}
OptionsMenu.js脚本运行结果如下:

你也应该改看看GUI.TextFieldGUI.TextArea这些控件允许你创建可编辑文字输入控件.

GUI.HorizontalSlider和GUI.verticalSlider

GUI.HorizontalSlider和GUI.verticalslider静态函数可相应的用于绘制水平和竖直滑块.滑块用于指定在一定范围内的一个数值.在上面的例子中,使用了两个水平滑块来指定主音量和音效范围为0到1

Slider函数接受当前滑块值和滑块最小值和滑块最大值.上面的例子展示了如何使用水平滑块,竖直滑块使用与水平滑块同样的参数只是滑块是竖直绘制而不是水平绘制.

下面的例子展示了使用竖直滑块来创建一个音频均衡器

#pragma strict

private var equalizerValues = new float[10];

function OnGUI()
{
	var groupWidth = 320;
	var groupHeight = 260;
	
	var screenWidth = Screen.width;
	var screenHeight = Screen.height;
	
	var groupX = (screenWidth - groupWidth) / 2;
	var groupY = (screenHeight - groupHeight) / 2;
	
	GUI.BeginGroup(Rect(groupX,groupY,groupWidth,groupHeight));
	GUI.Box(Rect(0,0,groupWidth,groupHeight),"Equalizer");
	
	for(var i = 0; i < equalizerValues.Length; i++)
	{
		equalizerValues[i] = GUI.VerticalSlider(Rect(i * 30 + 20,30,20,200),equalizerValues[i],0.0,1.0);
	}
	GUI.EndGroup();
}
结果应类似下面的:

当使用水平滑块时,最小值在滑块的左边最大值在滑块的右边.当使用竖直滑块时,最小值在顶部,最大值在滑块底部.

您可能也想看看GUI.HorizontalScrollbarGUI.VerticalScrollbar它们类似于滑块,但具有不同的功能。

GUI.WINDOW和GUI.DRAGWINDOW

GUI类提供了在屏幕上绘制窗口的函数,窗口可以使用外部函数(除了OnGUI)来渲染窗口的内容.

如果在窗口的回调函数中使用GUI.DragWindow函数,那窗口将会是可拖动的.

下面的代码创建了一个简单而可拖动的窗口

DraggableWindow.js

#pragma strict

//窗口的初始位置以及大小
private var windowRect0 = Rect(20,20,150,0);

function OnGUI()
{
	//渲染窗口ID为0
	windowRect0 = GUILayout.Window(0,windowRect0,WindowFunction,"Draggable Window");
}

function WindowFunction()
{
	GUILayout.Label("This is a draggable window!");
	
	//窗口的拖条(drag-strip),坐标相对于窗口的左上角
	GUI.DragWindow(Rect(0,0,150,20));
}
如果在新场景中将脚本应用到GameObject上,你就会看到窗口,点击并拖动窗口标题你就可以在屏幕上把窗口拖来拖去.

在窗口中可以放置任意数量的控件.如果你想要Unity在窗口中自动布局控件(就像例子中一样)那你应该使用GUILayout.Window函数而不是GUI.Window函数.当使用GUILayout.Window函数时,unity会自动修改窗口的高度以适应内容.就像上面的例子展示的一样.

自动布局

在这里展示的绝大数例子,我都是用GUI类来创建菜单.GUI类需要我们手动地在屏幕上放置空间,在某些情况下,手动摆放控件很有用,但如果你想要unity为你自动布局控件,那你需要使用GUILayout类.这个类提供了许多像GUI一样的功能,但不要求你指定控件的大小

GUILayout.beginHorizontal和guilayout.beginVertical

默认情况下,当使用GUILayout函数时所有的视图中的组件都会竖直排列.你可以使用guilayout.beginhorizontal和guilayout.endhorizontal静态函数使控件相邻排放.每出现一次guilayout.BeginVertical必须有对应的GUILayout.EndVertical与其对应,每出现一次GUILayout.BeginHorizontal则必须有对应的GUILayouyudHorizontal与其对应

下面的例子展示了如何使用竖直和水平布局来创建复杂的表格

UserForm.js

#pragma strict

private var firstName:String = "First Name";
private var lastName:String = "Last Name";
private var age:uint = 0;
private var submitted:boolean = false;

private var windowRect0:Rect;

function Start()
{
	
}

function OnGUI()
{
	var screenWidth = Screen.width;
	var screenHeight = Screen.height;

	var windowWidth = 300;
	var windowHeight = 180;
	var windowX = (screenWidth - windowWidth) / 2;
	var windowY = (screenHeight - windowHeight) / 2;

	//将窗口放置到屏幕中间
	windowRect0 = Rect(windowX,windowY,windowWidth,windowHeight);

	GUILayout.Window(0,windowRect0,UserForm,"User information");
}

function UserForm()
{
	GUILayout.BeginVertical();

	//first name
	GUILayout.BeginHorizontal();
	GUILayout.Label("First Name",GUILayout.Width(80));
	firstName = GUILayout.TextField(firstName);
	GUILayout.EndHorizontal();

	//last name
	GUILayout.BeginHorizontal();
	GUILayout.Label("Last Name",GUILayout.Width(80));
	lastName = GUILayout.TextField(lastName);
	GUILayout.EndHorizontal();

	//Age
	GUILayout.BeginHorizontal();
	GUILayout.Label("Age",GUILayout.Width(80));
	var ageText = GUILayout.TextField(age.ToString());
	var newAge = age;
	if(uint.TryParse(ageText,newAge))
	{
		age = newAge;
	}
	GUILayout.EndHorizontal();	

	if(GUILayout.Button("Submit"))
	{
		submitted = true;
	}
	if(GUILayout.Button("Reset"))
	{
		firstName = "First Name";
		lastName = "Last Name";
		age = 0;
		submitted = false;
	}
	if(submitted)
	{
		GUILayout.Label("submitted!");
	}
	GUILayout.EndVertical();
}
这段代码看上去挺复杂的.这里面有些东西如果你不熟悉脚本编写的话可能看起来不熟悉.需要强调的一点是我使用一个静态窗口(不可拖动)的来把控件据合起来.窗口需要一个绘制其内部结构的函数.为此我是用了UseForm函数.

用户表格开头使用竖直布局.因为当使用自动布局时竖直布局是默认的,所以显式的指定它是可有可无的.

之后每一个字段都是用水平布局创建,标签旁边跟着文本.标签被显式的使用GUILayout.Width()函数设置为80像素.我这样做是为了确保所有的文本都整洁的对齐.文本域扩展填充窗口的剩余部分.

在两个文本之后,添加了两个竖直布局的按钮.按钮将扩展填充区域其高度由按钮的内容决定.

不要忘了常使用GUILayout.EndVertical()或GUILayout.EndHorizontal()函数结果竖直或水平布局.

脚本UserForm.js将会产生如下结果:

你可能也想看看GUI.BeginGroup,GUILayout.BeginAreaGUI.BeginScrollView.所有的这些函数都可以被用于创建组(或者可以自动布局的区域),这些组或者区域可以用于保持控件在特定区域内聚合起来.

样式和皮肤

unity为所有的GUI控件提供了默认的外观.作为一个快速解决方案的话默认的样式足够用了,但你可能不想在你要面市的游戏中使用unity的默认GUI样式.

GUISkin

使用自定义的GUISkin你可以更改按钮,标签,滑块,和滚动条的外观.

GUISkin是一个套件(asset),你可以从主菜单中选择Assets>Create>GUISkin来创建它.

如果你在项目视图(project view)里选择了GUISkin,你可以为你可创建的多种控件编辑单独的样式设置.

要使用你自定义的皮肤将默认皮肤替换掉,在GUI脚本里面设置GUI.skin属性为你自定义的皮肤.将GUI.skin属性设置为null将还原回默认的GUISkin.

GUIStyle

GUISkin只是一系列GUIStyle样式的集合.GUIStyle定义了一个控件所有可变状态的样式.一个控件有以下状态:

  • 正常状态:控件的默认状态.鼠标既没有悬停到控件上控件也没有获得系统焦点.
  • 悬停状态:鼠标当前悬停在控件上
  • 注视状态:当前正选择控件,选中的控件将会接受键盘输入.这个状态对于按钮和可编辑文本控件.
  • 活动状态:控件被点击,这个状态对于按钮,滑块和滚动条都是合法的.

GUIStyle可以在没有GUISkin的情况下使用以便改写控件的样式.要使用GUIStyle,简单的在脚本中创建一个GUIStyle类型的公开变量并在检视器(inspecot),当你想要为控件应用样式.简单把样式作为控件函数的最后一个参数数传进去就行.

作为练习,下载下面的Unity包并将其导入一个新的Unity工程中:

链接地址

使用下面代码,创建一个名称为LevelSelect.js的脚本.

LevelSelect.js

#pragma strict
function OnGUI()
{
	var groundWidth = 120;
	var groundHeight = 150;
	
	var screenWidth = Screen.width;
	var screenHeight = Screen.height;
	
	var groupx = (screenWidth - groundWidth) / 2;
	var groupy = (screenHeight - groundHeight) / 2;
	
	GUI.BeginGroup(Rect(groupx,groupy,groundWidth,groundHeight));
	GUI.Box(Rect(0,0,groundWidth,groundHeight),"Level Select");
	
	if(GUI.Button(Rect(10,30,100,30),"Level 1"))
	{
		Application.LoadLevel(1);
	}
	if(GUI.Button(Rect(10,70,100,30),"Level 2"))
	{
		Application.LoadLevel(2);
	}
	if(GUI.Button(Rect(10,110,100,30),"Level 3"))
	{
		Application.LoadLevel(3);
	}
	
	GUI.EndGroup();
}
你可能注意到这就是上面按钮例子里面的代码,但是现在我们要为这些按钮设置一套自定的皮肤.

在检视器(inspector)中,在Button Style属性中设置如下选项:

  • Normal.Background: roundedButton_Normal.psd
  • Normal.Text Color: (0, 0, 0, 255)
  • Hover.Background: roundedButton_Hover.psd
  • Hover.Text Color: (0, 0, 0, 255)
  • Active.Background: roundedButton_Active.psd
  • Active.Text Color: (80, 80, 255, 255)
  • Border.Left: 6
  • Border.Right: 6
  • Border.Top: 6
  • Border.Bottom: 6
  • Padding.Left: 6
  • Padding.Right: 6
  • Padding.Top: 12
  • Padding.Bottom: 6
  • Font: SHOWG
  • Alignment: Middle Center

你会得到类似于下面的展示的.


Demo

下面是一个交互demo,它展示了如何使用多种控件,demo包含如下场景:

  • GUI基础:描述了OnGUI函数并展示了一个使用按钮和箱子(box)组件的例子
  • 控件:这个场景展示了多种你能创建的组件
  • 自定义:如何创建皮肤和样式
  • 布局:讲述了固定和自动布局模式.也展示了一个使用竖直和水平布局的例子
  • 扩展Unity编辑器:这个场景展示了一个如何在unity中创建自定义编辑器窗口.下载这个unity工程并将其加载到Unity来看自定义的编辑器窗口.

运行Demo

下载Demo

下载并解压zip文件,在unity编辑器中打开Assets/Scenes/Introduction.unity场景文件.

2013-10-14 11:07:48 hayaceo 阅读数 0
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

功能实现:


1.创建一个GUITexture : create-> GUITexure;


   此时可以通过修改component 栏中的选项,改变gui的texture等;


   这样建立的GUITexture从属于整个屏幕平面,作为一个新的物体出现,他的位置不受camera的位置的影响,


   就是说,不管camera移动到哪里,这个GUI始终在你设定的位置;


2. 将GUIslider.js附加到GUITexture上;maincamera作为其参数,应该将camera指定到上面;


GUIslider.js:
*/
var mainCamera:Camera;//将你自己的camera赋值到这个camera上面
var customButton : GUIStyle;// 为新出现的GUI设置Style
private var newPosition:Vector3;// GUI移动后新的位置
private var MouseUp: boolean;//显示Mouse是够是Up状态
private var getPosition : int = 0;//得到鼠标离开GUI的帧数
private var subGuiShowUp : int = 0;//统计帧数,控制subGUI出现
function Update () {
  
  if(MouseUp){
  if(getPosition < 12)
  {
     newPosition.x = mainCamera.ScreenToViewportPoint(Input.mousePosition).x;
  getPosition +=1;
  }
 if(Mathf.Abs(transform.position.x - newPosition.x) > 0.00001){
  transform.position.x += (newPosition.x  - transform.position.x)*Time.deltaTime*6;
  }
 }
  }
function OnMouseDrag(){
 MouseUp = false;
 subGuiShowUp +=1;
 getPosition = 13;
 transform.position.x += (mainCamera.ScreenToViewportPoint(Input.mousePosition).x  - transform.position.x)*Time.deltaTime*10;
}
function OnMouseUp(){
 print(transform.position.x);
 MouseUp = true;
 getPosition = 0;
 //subGuiShowUp = 25;
}
function OnGUI(){
   if(MouseUp){
 if(subGuiShowUp < 12){
 GUI.Button (Rect (5,5,100,100), "Hello World", customButton);
 }
 }
}
function OnMouseDown(){
   subGuiShowUp = 0;
}
2019-08-14 15:11:52 qq_37394634 阅读数 1518
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

个人博客:http://www.chenjianqu.com/

原文链接:http://www.chenjianqu.com/show-6.html

GUI简介

GUI是Graphical User Interface的缩写。Unity的图形界面系统能容易和快速创建出各种交互界面。游戏界面是游戏作品中不可或缺的部分,它可以为游戏提供导航,也可以为游戏内容提供重要的信息,同时也是美化游戏的一个重要手段。Unity内置了一套完整地GUI系统,提供了从布局、控件到皮肤的一整套GUI解决方案,可以做出各种风格和样式的GUI界面。目前Unity没有提供内置的GUI可视化编辑器,因此GUI界面的制作需要全部通过编写脚本代码来实现。

 

Unity创建GUI

GUI的代码需要写在OnGUI()这个函数里,每当重绘GUI的时候,都会执行这个方法。每一帧都会重绘GUI。

首先在Unity里面新建一个C#脚本,把它附加到任意一个游戏实体上。然后在脚本里面创建一个OnGUI()函数。如下图所示,我们打算创建一个Button控件。

1_20190112010956_298.png

创建函数返回的是一个bool值,当用户点击按钮时返回True,否则为False。创建大多数GUI控件都需要一个Rect对象用于设置控件的大小和位置。对于Button控件来说,第二个参数可以为一个字符串,也可以为图像。如下图:

2_20190112011007_448.png

运行效果:

3_20190112011014_810.png

对于GUI来说,屏幕的左上角为坐标原点,右下角的坐标为(Screen.Width,Screen.Height)。Rect对象的四个参数分别代表:控件左上角x坐标,控件左上角y坐标,控件的宽度,控件的高度。

 

常见的GUI控件:

Lable:绘制文本和图片

Box:绘制一个图形框

Button:绘制一个响应单击事件的按钮

RepeatButton:绘制一个处理连续按下事件的按钮

TextField:绘制一个单行文本输入框

PasswordField:绘制一个密码输入框

TextArea:绘制一个多行文本输入框

Togle:绘制一个开关

Toolbar:绘制一个工具条

SelectionGrid:绘制一组网格按钮

HorizontalSlider:绘制一个水平方向的滑动条

VerticalSlider:绘制一个垂直方向的滑动条

HorizontalScrollbar:绘制一个水平方向的滚动条

VerticalScrollbar:绘制一个垂直方向的滚动条

Window:绘制一个窗口,可以用于放置控件。

 

有个需要注意的地方,比如我代码这样写:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class GUILayout_Test : MonoBehaviour {
 
    // Use this for initialization
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () {
        
    }
 
   private void OnGUI()
    {
        if(GUI.RepeatButton(new Rect(10, 10, 100, 20), "你好"))
        {
            print("OK");
        }
        GUI.TextArea(new Rect(10, 30, 100, 20),"ABC");
    }

运行的结果如下:

4_20190112011050_164.png

从图中可知,当我长按“你好”按钮的时候,输出窗口会输出“OK”,也就是说,print(“OK”)被反复执行,这就是RepeatButton和Button的不同之处。

还有就是这个代码是无法对文本框里的ABC进行编辑的,要想编辑文本框正确的写法如下:

    private string str = "ABC";
    private void OnGUI()
    {
        if(GUI.RepeatButton(new Rect(10, 10, 100, 20), "你好"))
        {
            print("OK");
        }
        str=GUI.TextArea(new Rect(10, 30, 100, 20),str);
    }

其他需要改变内容的控件做法类似。

 

简单例子——绘制登录窗口:

    private string userName = "";
    private string password = "";
    private bool manSex = false;
    private bool womanSex = false;
    private void OnGUI()
    {
        GUI.Label(new Rect(10, 10, 70, 20), "用户名:");
        userName = GUI.TextArea(new Rect(80, 10, 200, 20), userName);
        GUI.Label(new Rect(10, 30, 70, 20), "密码:");
        password = GUI.PasswordField(new Rect(80, 30, 200, 20),password,'*');
        manSex = GUI.Toggle(new Rect(10, 70, 50, 20), manSex, "男");
        womanSex = GUI.Toggle(new Rect(10, 120, 50, 20), womanSex, "女");
        GUI.Button(new Rect(10, 170, 50, 20), "OK");
}

5_20190112011126_414.png

说明:PasswordField的第三个参数是掩盖密码的字符。

 

群组的使用

  有时候我们想更好的管理和排布控件,这个时候我们需要用到群组(Group)。

群组 (Groups) 是固定布局模式 (Fixed Layout Mode) 下可用的惯例,使您能够定义包含多个控件 (Controls) 的屏幕区域。您通过使用GUI.BeginGroup() 函数和GUI.EndGroup() 函数来定义哪些控件 (Controls) 在一个群组 (Group) 内。一个群组 (Group) 内的所有控件 (Controls) 都将基于群组 (Group) 的左上角来放置而不是按屏幕的左上角。以此方式,当您在运行时重新调整该群组的位置时,群组内所有控件 (Controls) 的相对位置保持不变。

 

例如,可以很容易地把多个控件 (Controls) 放置在屏幕中心:

    void OnGUI () {
        // 在屏幕中心创建群组
        GUI.BeginGroup (new Rect (Screen.width / 2 - 50, Screen.height / 2 - 50, 100, 100));
        // 所有矩形经调整以适应于群组,其中(0,0)是群组的左上角
        // 创建框以便于知道群组在屏幕上的位置
        GUI.Box (new Rect (0,0,100,100), "Group is here");
        GUI.Button (new Rect (10,40,80,30), "Click me");
 
        // 结束前面开始的群组。这很重要,请记住!
        GUI.EndGroup ();
}

6_20190112011207_761.png

 

也可以将多个群组 (Group) 嵌套进彼此内部。进行嵌套后,每个群组的内容都被剪切到其父级空间:

using UnityEngine;
using System.Collections;
 
public class GUITest : MonoBehaviour {
 
    // 256 x 32 背景图像
    public Texture2D bgImage;
 
    // 256 x 32 前景图像
    public Texture2D fgImage;
 
    // 0.0 和 1.0 之间的一个浮点数
    public float playerEnergy = 1.0f;
 
    void OnGUI () {
        // 创建群组 (Group) 来容纳两幅图像
        // 调整开始的 2 个坐标以便将其放置在屏幕上的其他某处
        GUI.BeginGroup (new Rect (0,0,256,32));
 
        // 绘制背景图像
        GUI.Box (new Rect (0,0,256,32), bgImage);
 
            // 创建将被剪切的第二群组 (Group)
            // 我们要剪切而不是缩放图像,所以需要第二群组 (Group)
            GUI.BeginGroup (new Rect (0,0,playerEnergy * 256, 32));
 
            // 绘制前景图像
            GUI.Box (new Rect (0,0,256,32), fgImage);
 
            // 结束两个群组 (Groups)
            GUI.EndGroup ();
 
        GUI.EndGroup ();
    }
}

7_20190112011234_150.png

使用GUI Layout进行控件的布局

在上面我们对控件布局的时候都是手动计算控件的位置和长宽,不仅很麻烦,而且对不同分辨率设备,这种根据像素点的空间参数可能会发生错误,因此我们需要寻求一种新的解决方案。

这个更好的解决方案就是GUI Layout。自动布局(Automatic Layout)。有时候开发者不太在乎控件的精确位置,而只是想让它们按一些简单方式显示出来就OK的情况,或者说,当你之前不知道需要多少元素,或者不想手动安置每个控件时,可以使用自动布局。比如,当您要根据保存游戏文件来创建若干不同按钮时,您可能不知道要绘制按钮的确切数目。在这种情况下使用自动布局会更方便。

如果希望使用自动布局,只需要使用GUlLayout类来替代前面例子中使用的GUI类,并去掉用Rect()指定的位置参数即可。

常见的GUILayout有四种:水平GUILayout、垂直GUILayout、滚动GUILayout和区域GUILayout。默认的是垂直方式的。

垂直GUILayout和横向GUILayout的使用:

private void OnGUI()
    {
        GUILayout.BeginHorizontal();
        GUILayout.Button("你好啊");
        GUILayout.Button("你好啊");
        GUILayout.Button("你好啊");
        GUILayout.Button("你好啊");
        GUILayout.EndHorizontal();
 
        GUILayout.BeginVertical();
        GUILayout.Button("你好啊");
        GUILayout.Button("你好啊");
        GUILayout.Button("你好啊");
        GUILayout.Button("你好啊");
        GUILayout.EndVertical();
 
    }

8_20190112011303_972.png

 

可滚动的GUILatout:

private Vector2 sp;
private void OnGUI(){
   sp = GUI.BeginScrollView(new Rect(0, 0, 200, 200), sp, new Rect(0, 0, Screen.width, 400));
  GUI.Label(new Rect(100, 200, Screen.width, 50), "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
  GUI.EndScrollView();
}

参数说明:

第一个rect是它的可见区域大小以及位置,sp储存的是横向的滚动条以及纵向的滚动条的初始值。

第二个rect储存的是整体视图的大小(不大于屏幕大小)。值得一提的是它后面还可以添加两个bool值。分别控制横纵滚动条在没有出现无法观看的内容的时候是否出现滚动条。

9_20190112011415_459.png

 

 

区域GUILayout的使用:

区域 (Areas) 只在自动布局 (Automatic Layout) 模式中使用。区域在功能上与固定布局群组类似,因为它们定义了屏幕中有限的一部分来容纳 GUILayout 控件。由于自动布局 (Automatic Layout) 特性的原因,您几乎会总是用到区域 (Area)。

在自动布局 (Automatic Layout) 模式中,也可以不在控件层 (Control level) 定义要绘制控件的屏幕区域。控件 (Control) 将被自动放置到容纳区域的最左上角。这有可能是屏幕。您也可以创建手动放置区域 (Areas)。区域内的 GUILayout 控件 (GUILayout Control) 将被放置到该区域的最左上角。

代码示例:  

  private void OnGUI()
    {
        GUILayout.Button("I am not inside an Area");
        GUILayout.BeginArea(new Rect(Screen.width / 2, Screen.height / 2, 300, 300));
        GUILayout.Button("I am completely inside an Area");
        GUILayout.EndArea();
 
    }

10_20190112011448_740.png

注意,在一个区域 (Area) 内,带按钮 (Buttons)、框 (Boxes) 等可见元素的控件都会将其宽度拉伸至区域 (Area) 的全长。

 

GUILayout传入参数:

如果想对自动布局的控件参数施加一些控制,可以使用GUlLayout参数。例如,当按钮上的文字很长的时候,使用GUILayout.Button绘制的按钮宽度会特别长,这时候可以传入GUlLayout参数来限制它的长度。如下:

    private void OnGUI()
    {
        GUILayout.BeginArea(new Rect(100, 50, Screen.width - 200, Screen.height - 100));
        GUILayout.Button("I am a regular Automatic Layout Button OK OK qwertyuiop[asdfghjkl;zxcvbnm");
        GUILayout.Button("My width has been overridden", GUILayout.Width(95));
        GUILayout.EndArea();
       
}

显示的效果为:

11_20190112011510_343.png

 

 

参考文献

[1]仙峰游戏:周宝森. Unity教程:GUI界面开发. https://www.xf.com/gonglue/113801.2018.9.04

[2]博客园:Tonge.Unity3D深入浅出-GUI控件.

https://www.cnblogs.com/tonge/p/3935065.html.2014.8.27

[3]CSDN博客:wobushitankun. unity 3d GUI.BeginScrollView 介绍.

https://blog.csdn.net/wobushitankun/article/details/53510948.2016-12-7

[4]博客园:rainmj. 【Unity】8.3 布局模式(GUILayout).

https://www.cnblogs.com/rainmj/p/5437395.html.2016-04-27

2013-09-02 15:57:14 jbjwpzyl3611421 阅读数 23749
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

这一段将解释UnityGUI控制所需的脚本。
UnityGUI控制
  UnityGUI控制是利用一类被称为OnGUI()的函数,只要在控制脚本激活的状态下,OnGUI()函数可以在每帧调用,就像Update( )函数一样。
  GUI控制在结构上相当简单,这种结构在下面这个例子中十分明显:
/* Example level loader */

function OnGUI ()
{// Make a background box
 GUI.Box (Rect (10,10,100,90), "Loader Menu");

 // Make the first button. If it is pressed, Application.Loadlevel (1) will be executed
 if (GUI.Button (Rect (20,40,80,20), "Level 1")) {
  Application.LoadLevel (1);
 }

 // Make the second button.
 if (GUI.Button (Rect (20,70,80,20), "Level 2")) {
  Application.LoadLevel (2);
 }
}
  这个例子是一个完整的,功能层的装载,如果你把这段脚本复制粘贴到GameObject上,在Play模式下你将会看到如下的菜单出现。
       
  这个装载菜单是由例子中的代码创建的。
  下面让我们看一下这个例子中代码的细节:
  在GUI的第一行中,GUI.BOX (Rect(10,10,100,90),”Loader Menu”);通过头文本“Loader Menu”显示一个Box控制,它通过一个典型的GUI控制定义,这样我们可以在第一时间解释。
  在GUI的下一行中是一个Button控制定义,要注意它与BOX控制之间细微的差别。确切的说,整个Button定义放置在一个if语句中。当游戏在运行中并且按钮按下,if语句返回一个true,并且if中的代码被执行。
  当OnGUI()代码在每一帧被调用的时候,你不必明确的创建或去除GUI控制,定义控制的代码同时也创建了它。如果你需要在一个特定的时间显示控制,你可以利用任何一种描述逻辑来做。
/* Flashing button example */

function OnGUI () {
 if (Time.time % 2 < 1) {
  if (GUI.Button (Rect (10,10,200,20), "Meet the flashing button")) {
   print ("You clicked me!");
  }
 }
}
  这里,GUI.Button()只有在其它时间上才会被调用,所以按钮会出现或消失,自然地,用户只有在在按钮可见的情况下才能按下它。
  就像你所看见的,当GUI控制显示和工作时,你可以利用任何希望的逻辑去控制。现在,我们来详细的研究每个控制定义。

Anatomy of a Control (控制的解剖)
  当GUI控制定义时,这里有三种关键信息:
Type(Position,Content)
  很明显这种结构是一个函数有两个内容来描述,下面我们解释这种结构的细节。
Type
  Type是一种控制类型,通过调用Unity的GUI class或者是GUILayout Class函数来定义,只有在布局模式中讨论长度才会用到。例如,GUI.Label()将会创建一个非交互的标签。所有不同的控制类型会在后面解释,在导读的控制部分。
Position
  Position是第一个需要描述的GUI函数,它通过提供Rect()函数来描述自己,Rect()定义四种工具,最左端位置,最上端位置,总宽度和总高度。所有的值只能是整数,相当于像素值。所有的UnityGUI控制工作在屏幕空间,发布的播放窗口的像素分辨率。
  坐标系以左上为基础,Rect(10,20,300,100)定义一个矩形:10,20的位置开始,310,120的位置结束。Rect函数后面两个整数是定义的总宽和总高,而不是绝对位置上的宽和高,这就是为什么例子上提到的是310,120而不是300,100.
  你可以利用屏幕宽度和屏幕高度工具得到总的屏幕播放器尺寸,下面这个例子将帮助我们清楚它是怎么工作的:
/* Screen.width & Screen.height example */

function OnGUI () {
 GUI.Box (Rect (0,0,100,50), "Top-left");
 GUI.Box (Rect (Screen.width - 100,0,100,50), "Top-right");
 GUI.Box (Rect (0,Screen.height - 50,100,50), "Bottom-right");
 GUI.Box (Rect (Screen.width - 100,Screen.height - 50,100,50), "Bottom-left");
}
 
  这个盒子位置就是上面的例子

Content
  GUI控制的第二个描述就是控制所显示的实际内容,大多数情况下你要显示一些文本或是图片在你的控制上,显示一段文本,通过下面一段Content代码:
/* String Content example */

function OnGUI () {
 GUI.Label (Rect (0,0,100,50), "This is the text string for a Label Control");
}
显示一副图片,定义一个2D材质变量,通过变量的名称定义内容。
/* Texture2D Content example */

var controlTexture : Texture2D;

function OnGUI () {
 GUI.Label (Rect (0,0,100,50), controlTexture);
}
下面是一个与真实世界脚本比较接近的例子:
/* Button Content examples */

var icon : Texture2D;

function OnGUI () {
 if (GUI.Button (Rect (10,10, 100, 50), icon)) {
  print ("you clicked the icon");
 }

 if (GUI.Button (Rect (10,70, 100, 20), "This is text")) {
  print ("you clicked the text button");
 }
}
 
  这个按钮时通过上面的例子创建的

  这里有第三种选择可以使你把图片和文字一起在GUI中显示,你可以提供一个物体类似于内容描述,并且定义一串代码和图片在GUI内容中显示。
/* Using GUIContent to display an image and a string */

var icon : Texture2D;

function OnGUI () {
 GUI.Box (Rect (10,10,100,50), GUIContent("This is text", icon));
}
你也可以在GUI中定义一个Tooltip,它可以在GUI中你的鼠标停留的地方显示。
/* Using GUIContent to display a tooltip */

function OnGUI () {
 // This line feeds "This is the tooltip" into GUI.tooltip
 GUI.Button (Rect (10,10,100,20), GUIContent ("Click me", "This is the tooltip"));
 // This line reads and displays the contents of GUI.tooltip
 GUI.Label (Rect (10,40,100,20), gui.tooltip);
}
如果你敢,你一样可以利用GUIContent显示一串代码、一个符号或是一个tooltip
/* Using GUIContent to display an image, a string, and a tooltip */

var icon : Texture2D;

function OnGUI () {
 GUI.Button (Rect (10,10,100,20), GUIContent ("Click me", icon "This is the tooltip"));
 GUI.Label (Rect (10,40,100,20), gui.tooltip);
}
这段涉及到GUIContent的结构那页,有大量的例子。

 

Unity3D笔记 GUI 一

阅读数 0