1.GUI相关内容复习
2.主界面GUI框架搭建
3.场景转换设置
GUI全称为Graphical User Interface,指的是用户图形界面,在各种软件程序,特别是在游戏中,GUI无处不在(头像,文字,开始菜单按钮,血条,音量调节器…),一般是由美工人员来设计,程序员来完成交互的相关逻辑。
Unity中有GUI类,所有基本的UI控件大都在这个类里面,使用这些控件有两个方法:
1.直接在界面上拖,菜单创建(很不灵活,不利于理解原理,极度不推荐)
2.在脚本中用代码创建,使用(nice!)
本文主要总结第二种方法。
GUI与游戏界面,场景是完全分开的,它存在于一个大的canvas上,固定在游戏屏幕上,游戏中镜头移动不会影响到GUI的显示。一般选择创建一个单独的脚本来控制GUI,然后绑到一个空的GameObject上。
Unity的Monobehaviour中有OnGUI()方法,每一帧调用一次,也就是说GUI是每一帧会刷新的,这是一个坑点。
1.Label
显示文字,很常用。方法是GUI.Label() ,来一段最简单的
GUI.Label(new Rect(10, 10, 100, 100), "Hello World!");
一般是这样用,方法的第一个参数是位置和大小,new一个矩形来表示,第二个参数是一个string,显示文字内容。当然还有其他的样式设置,在其重载方法中,用到的时候再说吧。
2.TextField (输入框)
文本输入框,较为常用,但是有一个小坑,新手必掉。
GUI.TextField(new rect,"");基本方法是这样,但这么做真的能得到输入的东西吗?肯定不行。要记住GUI是每帧刷新一次,OnGUI方法也是每帧调用一次,就算输入了东西,游戏也确实接收到了,也显示不出来,因为输入后0.02秒左右它就又变回“”了。因此需要把内容保存下来,定义一个string变量,进行实时更新。示例代码如下:
private string strInput1="我是文本";//初始化时定义
strInput1=GUI.TextField(new Rect(160, 10, 100, 100), strInput1);
//每一次都将strinput更新
还有其他继承的TextArea,PasswordField等也都是这个原理
3 .Button
非常常用,应用很广(各种交互,菜单选择,设置等),主要是用其点击事件。同样是第一个参数为rect,第二个为string(显示内容)
GUI.Button(new Rect(new Vector2(10, 310), new Vector2(100, 35)), "start");
这算是一个基本的定义,要接收其被按下的事件一般直接放if语句里。随便写个示例代码:
public bool ClickFlag = false;//initialize
//OnGUI
if(GUI.Button(new Rect(50,50,100,40),"Click"))
{
ClickFlag = !ClickFlag;
}
if(ClickFlag==true)
{
GUI.Label(new Rect(160, 100, 100, 50), "The button was clicked");
}
也要注意每帧刷新的问题…
还有一个RepeatButton,用法类似,区别在于它接收的是鼠标按下的事件,相当于可以长按,在一些立体模型的演示上很有用。
4 .ToolBar
一般用于TAB键显示信息之类的,或者是选项卡
返回一个整形,在初始化中定义一个int来储存,方法中第一个参数是位置(rect),第二个是int参数,第三个是一个字符串数组
private int _IntSelectIndex = 0;//initialize
//onGUI
_IntSelectIndex = GUI.Toolbar(new Rect(50, 160, 200, 30),
_IntSelectIndex, new string[] { "Name", "Age", "Level" });
5.Toggle
复选框,不太常用,一般是在画面设置中打勾用的,比如:
垂直同步 ()
环境光 ()…
打勾即选中,将bool值置为true,可以做相应的判断。附上示例代码:
private bool _BoolCheck1 = false;
//selection controller (return bool)
BoolCheck1 = GUI.Toggle(new Rect(50, 200, 100, 40), _BoolCheck1, "I Love You");
基本用到的大概就这些,之后有其他的再补充。这里再介绍两个东西:
1.自动布局
GUILayout 方法与GUI类似,但不需要传入rect来确定位置,编辑器会自动排版(若要加限制,则使用重载带有GUILayout.width(),GUILayout.Space()的方法)如:
GUILayout.BeginArea(new Rect(0, 0, 500, 600));
//自动布局
GUILayout.Label("我是自动布局,不需要rect()");
//return a string
_StrInput1=GUILayout.TextArea(_StrInput1, GUILayout.Width(100));
//create a Button
GUILayout.Button("Layout",GUILayout.Width(70));
GUILayout.Space(100);
//return a string
_StrInput1 = GUILayout.TextArea(_StrInput1, GUILayout.Width(100));
//create a Button
GUILayout.Button("Layout", GUILayout.Width(70));
2 .GUISkin
默认的控件样式很丑,在工程中创建一个GUISkin,设置其样式(在Custom Style栏中可以创建多个按钮样式) ,再拖入对应想要的字体,贴图等,在脚本中进行调用(一般是GUI里方法的最后一个参数)
public GUISkin ProjectSkin;
public Texture2D TexPic_1;//initialize
void Start () {
GUI.skin = ProjectSkin;
}
void OnGUI(){
GUI.Button(new Rect(100, 100, TexPic_1.width, TexPic_1.height), "",ProjectSkin.GetStyle("BTN_1"));
}
先就整理这么多,下面应用到跑酷游戏上
一.首先在_Scripts创建一个文件夹来放GUI的脚本,再创建一个StartSceneGUI的脚本来专门控制开始场景的GUI。
二.创建一个GUISkin命名为ProjectSkin,在CustomStyle项中添加多个elements,来放对应按钮的贴图。命好名后把对应的贴图拖到normal项的background中。
在StartSceneGUI脚本中定义并加入:
public GUISkin ProjectSkin;
//onGUI
GUI.skin = ProjectSkin;
三.创建开始和退出的按钮
要注意按钮的位置,先获取屏幕的正中(用Screen.width来获取),再获取贴图的大小(Texture.width),作为参数
定义部分:
public Texture2D TxtPlay;
public Texture2D TxtExit;
public Texture2D TxtVolume;
private bool _BoolPlayGame;
private bool _BoolExitGame;
实现部分:
//start button
if (GUI.Button(new Rect(Screen.width/2-TxtPlay.width/2,
Screen.height/2+80,TxtPlay.width, TxtPlay.height), "", ProjectSkin.GetStyle("Btn_Play")))
{
_BoolPlayGame = true;
}
//exit button
if (GUI.Button(new Rect(Screen.width / 2 - TxtExit.width / 2,
Screen.height / 2 + 130, TxtExit.width, TxtExit.height),"", ProjectSkin.GetStyle("Btn_Exit")))
{
_BoolExitGame = true;
}
四.实现场景转换
又是版本问题,旧版本的Application.LoadLevel()方法已经弃用,现在是用SceneManager了,于是去查一查API
可知需要using UnityEngine.SceneManagement;
创建一个新的场景,并在菜单Build setting中注册场景,记下场景的index(容易忘记,需注意)
然后就通过上面定义的bool值来控制场景转换就OK了
if(_BoolPlayGame)
{
SceneManager.LoadScene(1);
}
if(_BoolExitGame)
{
Application.Quit();
}
五.绑定脚本
创建一个空GameObject,把脚本拖进去,然后把对应贴图拖到对应的变量位置上,皮肤也拖进去,完成。
附上完整的代码:
非常简单,运行出来也没问题,再加一个天空盒子来补一下光线,明天开始正式设计第一关咯