分类:Unity、C#、VS2015
创建日期:2016-04-27
一、简介
在Unity 5.x中,GUI控件的布局方式有两种。
一种为固定布局,即在绘制控件的时候将位置参数传入,指定控件的精确位置。另一种是自动布局,适用于控件数量动态改变的情况。或者说,当你已经有了一个预先设计好的界面可以用来工作时,可以使用固定布局 (Fixed Layout)。
另一种为自动布局(Automatic Layout)。有时候开发者不太在乎控件的精确位置,而只是想让它们按一些简单方式显示出来就OK的情况,或者说,当你之前不知道需要多少元素,或者不想手动安置每个控件时,可以使用自动布局。比如,当您要根据保存游戏文件来创建若干不同按钮时,您可能不知道要绘制按钮的确切数目。在这种情况下使用自动布局会更方便。
如果希望使用自动布局,只需要使用CUlLayout类来替代前面例子中使用的GUI类,并去掉用Rect()指定的位置参数即可。
使用自动布局 (Automatic Layout) 时,存在两个关键的不同之处:
- 使用 GUILayout,而非 GUI
- 自动布局 (Automatic Layout Controls) 控件无需 Rect() 函数
例如:
using UnityEngine; using System.Collections; public class GUITest : MonoBehaviour { void OnGUI () { // Fixed Layout GUI.Button (new Rect (25,25,100,30), "I am a Fixed Layout Button"); // Automatic Layout GUILayout.Button ("I am an Automatic Layout Button"); } }
在固定布局 (Fixed Layout) 中,可以将不同的控件 (Controls) 放入 群组 (Groups) 。在自动布局 (Fixed Layout) 中,可以将不同的控件 (Controls) 放入 区域 (Areas)、水平群组 (Horizontal Groups) 和垂直群组 (Vertical Groups)。
在OnGUI()函数中,也可以混合使用固定布局和自动布局两种方式。
二、固定布局
群组 (Groups) 是固定布局模式 (Fixed Layout Mode) 下可用的惯例,使您能够定义包含多个控件 (Controls) 的屏幕区域。您通过使用GUI.BeginGroup() 函数和GUI.EndGroup() 函数来定义哪些控件 (Controls) 在一个群组 (Group) 内。一个群组 (Group) 内的所有控件 (Controls) 都将基于群组 (Group) 的左上角来放置而不是按屏幕的左上角。以此方式,当您在运行时重新调整该群组的位置时,群组内所有控件 (Controls) 的相对位置保持不变。
例如,可以很容易地把多个控件 (Controls) 放置在屏幕中心:
using UnityEngine; using System.Collections; public class GUITest : MonoBehaviour { 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 (); } }
效果如下:
也可以将多个群组 (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 (); } }
效果如下:
三、自动布局
1、Area
自动布局的确省了不少事,毕竟有时候在开发调试阶段不需要太关注GUI控件的精确摆放位置。但是当控件多了之后,全都自动布局就会显得太杂乱,这时候可以使用GUIlLayout.BeginArea和GUILayout.EndArea来指定自动布局要摆放的区域。换言之,通过这种方式,可对显示区域进行大致的划分。
区域 (Areas) 只在自动布局 (Automatic Layout) 模式中使用。区域在功能上与固定布局群组类似,因为它们定义了屏幕中有限的一部分来容纳 GUILayout 控件。由于自动布局 (Automatic Layout) 特性的原因,您几乎会总是用到区域 (Area)。
在自动布局 (Automatic Layout) 模式中,也可以不在控件层 (Control level) 定义要绘制控件的屏幕区域。控件 (Control) 将被自动放置到容纳区域的最左上角。这有可能是屏幕。您也可以创建手动放置区域 (Areas)。区域内的 GUILayout 控件 (GUILayout Control) 将被放置到该区域的最左上角。
using UnityEngine; using System.Collections; public class GUITest : MonoBehaviour { 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 (); } }
注意,在一个区域 (Area) 内,带按钮 (Buttons)、框 (Boxes) 等可见元素的控件都会将其宽度拉伸至区域 (Area) 的全长。
2、水平组和垂直组
在使用控件自动布局时,默认的摆放方式是从上到下依次排列绘制,如果想将控件在某些情况下水平排列,某些情况下垂直排列,可以通过水平组和垂直组进行控制,使用方式是调用GUILayout.BeginHorizontal和GUILayout.EndHorizontal设置水平组,调用GUILayout.BeginVertial和GUILayout.EndVertial设置垂直组。
水平组和垂直组可以嵌套使用。
using UnityEngine; using System.Collections; public class GUITest : MonoBehaviour { private float sliderValue = 1.0f; private float maxSliderValue = 10.0f; void OnGUI() { // 将所有内容纳入指定 GUI 区域 GUILayout.BeginArea (new Rect (0,0,200,60)); // 开始单个水平群组 (Horizontal Group) GUILayout.BeginHorizontal(); // 按常规放置按钮 (Button) if (GUILayout.RepeatButton ("Increase max\nSlider Value")) { maxSliderValue += 3.0f * Time.deltaTime; } // 将另外两个控件垂直地放在按钮 (Controls) 旁边 GUILayout.BeginVertical(); GUILayout.Box("Slider Value: " + Mathf.Round(sliderValue)); sliderValue = GUILayout.HorizontalSlider (sliderValue, 0.0f, maxSliderValue); // 结束群组 (Groups) 和 区域 (Area) GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.EndArea(); } }
效果如下:
3、GUILayout参数
如果想对自动布局的控件参数施加一些控制,可以使用GUlLayout参数。例如,当按钮上的文字很长的时候,使用GUILayout.Button绘制的按钮宽度会特别长,这时候可以传入GUlLayout参数来限制它的长度。
using UnityEngine; using System.Collections; public class GUITest : MonoBehaviour { void OnGUI () { GUILayout.BeginArea (new Rect (100, 50, Screen.width-200, Screen.height-100)); GUILayout.Button ("I am a regular Automatic Layout Button"); GUILayout.Button ("My width has been overridden", GUILayout.Width (95)); GUILayout.EndArea (); } }