本章介绍GUI相关基础知识,使用老版UnityGUI进行测试。
本文仅供个人记录和复习,不用于其他用途
什么是GUI
举个简单的例子,像是游戏中的血条栏、经验栏等等,都是一直显示在游戏画面上的。不管是玩家走到哪里,或者杀了什么怪,这些元素都不会消失。因此,GUI 永远显示在屏幕上,不受光照、碰撞等因素影响。
平面坐标系
由于 GUI 是直接显示在屏幕上的,那么这里就不得不提一下坐标系了:
- 屏幕坐标系是以屏幕左下角为(0, 0)点,右上角为(Screen.Width, Screen.Height)
- 鼠标位置坐标系与屏幕坐标系一致
- 视口(View Port)坐标是以摄像机为准,屏幕左下角为(0, 0),右上角为(1, 1)
- 绘制 GUI 界面时使用的坐标是以屏幕的左上角为(0, 0)点,右下角为(Screen.Width, Screen.Height)
GUI 是以左上角为原点,其他的则是以左下角为原点,记住这一点即可。
OnGUI方法
UnityGUI曾经是官方的UI实现方法,不过 4.x 之后便推出了最新的uGUI系统,所以如果是要进行开发的话,还是推荐使用uGUI(之后会讲),这篇文章只用UnityGUI进行测试。UnityGUI提供了一个 OnGUI() 方法,OnGUI 会在每帧进行擦除、重绘,并实现相应的UI。下面来写一个简单的文本框:
|
|
新建一个空的对象,将这个脚本连接到对象上后执行,效果如下:
那么这个文本框就会默认显示一段话Hello World!
。
OnGUI的擦除与重绘
虽然文本框是显示出来了,但当你真正去用它的时候就会有一个问题:不管你输入什么,文本框显示的内容都不变。
事实上,这涉及到了 OnGUI 方法的擦除与重绘。当你输入字符时,文本框确实是接收到了,但由于 OnGUI 每帧都会进行擦除,你所输入的内容便会在那一帧的结尾被去除掉,而下一帧所绘制的又将是默认的Hello World!
。由于一秒有几十帧刷新,所以看起来就像是文本框没有收到输入内容。
看到这,想必你会有疑问,这种不停地擦除重绘有什么用?我又该如何显示我想要看到的内容?
解决方法
我们只需要在类中声明一个成员变量,并用它来储存字符串的内容:
|
|
在上述代码中,我们声明了一个私有的字符串 txt1,并且用它来存储字符串。注意,TextField() 的返回值就是用户在文本框中输入的字符串。
这样,我们就解决了擦除重绘的问题。
GUILayout布局
GUILayout 默认垂直布局,如果想要改成水平布局,可以这么做:
|
|
代码中用到了 BeginHorizontal() 和 EndHorizontal()。显然,所有在这两个方法之间的控件都将以水平方式排布。另外,你可以任意嵌套水平布局与垂直布局,达到自己想要的效果。
GUILayout 布局会自动调整控件的尺寸,如果你想要自定义控件的长度,那么 Button 等控件也支持可变参数数组。例如:
|
|
GUILayou.Width(30)
会返回一个设置空间宽度的 GUILayoutOption 对象,Height、MinWidth、MinHeight 同理,可以随自己的需要调用。
另外,如果是觉得控件之间太挤,可以使用GUILayout.Space()
来调整间隙。
总结
最后再次强调一遍,OnGUI 是每帧都会进行擦除重绘的。如果想要的内容没有显示出来,可以自己创建一个变量,从而保证文本框中显示的值与返回的值使用同一个变量。