工作原理和主要作用

GUI是什么

全称,即时模式游戏用户交互界面(IMGUI)

Unity中简称为GUI

它是一个代码驱动的UI系统

GUI的主要作用

1.作为程序员的调试工具,创建游戏内调试工具

2.为脚本组件创建自定义检视面板

3.创建新的编辑器窗口和工具以拓展Unity本身(一般作为内置游戏工具)

不要用它为玩家制作UI功能

1
2
3
4
private void OnGUI()
{
//在其中书写GUI相关代码,即可显示GUI内容
}

OnGUI每帧执行

一般只在其中执行GUI相关界面绘制和逻辑操作

该函数在OnDisable之前,LateUpdate之后

只要是继承Mono的脚本,都可以在OnGUI中绘制UI

重要参数及文本和按钮

GUI绘制的共同点

1.都是GUI公共类中提供的静态函数,直接调用即可

2.他们的参数都大同小异

3.每一种控件都有多种重载,都是各个参数的排列组合

文本控件

1
2
3
4
5
private void OnGUI()
{
//Unity会用反射调用这个函数
GUI.Label(new Rect(0,0,100,20),"大家好我叫紫地丁");
}

将脚本挂到MainCamera上,运行游戏

屏幕截图 2023-04-27 220048

GUI的原点是屏幕的左上角

使用图片

1
2
3
4
5
6
7
public Texture tex;
public Rect rect;
private void OnGUI()
{
GUI.Label(new Rect(0,0,100,20),"大家好我叫紫地丁");
GUI.Label(rect,tex);
}

我们可以在检视器中调整图片的位置和宽高

综合使用

1
2
3
4
5
6
7
8
9
public Texture tex;
public Rect rect;
public GUIContent content;
private void OnGUI()
{
GUI.Label(new Rect(0,0,100,20),"大家好我叫紫地丁");
GUI.Label(rect,tex);
GUI.Label(rect,content);
}

屏幕截图 2023-04-27 221046

GUI.tooltip可以获取此时鼠标所在的GUI的Tooltip信息

1
Debug.Log(GUI.tooltip);

自定义样式

GUIStyle类用来自定义GUI样式

1
2
3
4
5
6
7
8
9
10
11
public Texture tex;
public Rect rect;
public GUIContent content;
public GUIStyle style;
private void OnGUI()
{
GUI.Label(new Rect(0,0,100,20),"大家好我叫紫地丁",style);
GUI.Label(rect,tex,style);
GUI.Label(rect,content,style);
Debug.Log(GUI.tooltip);
}

屏幕截图 2023-04-27 221718

按钮控件

1
2
3
4
5
6
7
public Rect btnRect;
public GUIContent btnContent;
public GUIStyle btnStyle;
private void OnGUI()
{
GUI.Button(btnRect, btnContent, btnStyle);
}

监听按钮的点击

GUI.Button有返回值,返回按钮是否被点击

1
2
3
4
5
6
7
8
9
10
public Rect btnRect;
public GUIContent btnContent;
public GUIStyle btnStyle;
private void OnGUI()
{
if (GUI.Button(btnRect,btnContent, btnStyle))
{
Debug.Log("点击");
}
}

制作一个长按按钮

使用GUI.RepeatButton

1
2
3
4
5
6
7
8
9
10
11
public Rect btnRect;
public GUIContent btnContent;
public GUIStyle btnStyle;

private void OnGUI()
{
if (GUI.RepeatButton(btnRect, btnContent))
{
Debug.Log("长按点击");
}
}

多选框和单选框

多选框

普通样式

1
2
3
4
private void OnGUI()
{
GUI.Toggle(new Rect(0, 0, 100, 20), true, "效果开关");
}

切换状态

GUI.Toggle会返回当前帧的状态

1
2
3
4
5
private bool _isSel;
private void OnGUI()
{
_isSel = GUI.Toggle(new Rect(0, 0, 100, 20), _isSel, "效果开关");
}

自定义样式

解决图片大小问题:改变FixedWidth和FixedHeight的值

改变状态:改变Normal和OnNormal的值

修改从GUIStyle到内容起始处的空间:padding

单选框

单选框是基于多选框实现的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using UnityEngine;
public class Lesson_3 : MonoBehaviour
{
private int _nowSelIndex=1;

private void OnGUI()
{
if (GUI.Toggle(new Rect(0, 0, 100, 30), _nowSelIndex == 1, "选项1"))
{
_nowSelIndex = 1;
}
if (GUI.Toggle(new Rect(0, 150, 100, 30), _nowSelIndex == 2, "选项2"))
{
_nowSelIndex = 2;
}
if (GUI.Toggle(new Rect(0, 300, 100, 30), _nowSelIndex == 3, "选项3"))
{
_nowSelIndex = 3;
}
}
}

输入框和拖动条

输入框

普通输入

1
2
3
4
5
private string inputStr = "请输入内容";
private void OnGUI()
{
inputStr = GUI.TextField(new Rect(0, 0, 100, 30), inputStr);
}

也有可以限制字符数量的重载

1
inputStr = GUI.TextField(new Rect(0, 0, 100, 30), inputStr,5);

密码输入

1
2
3
4
5
private string inputPw;
private void OnGUI()
{
inputPw = GUI.PasswordField(new Rect(0, 50, 100, 30), inputPw, '*');
}

拖动条

水平拖动条

1
2
3
4
5
6
7
8
public class Lesson4 : MonoBehaviour
{
private float _nowValue;
private void OnGUI()
{
_nowValue = GUI.HorizontalScrollbar(new Rect(0,100,100,50),_nowValue,0.1f,0f,1f);
}
}

竖直拖动条

1
_nowValue = GUI.VerticalScrollbar(new Rect(0, 100, 100, 50), _nowValue, 0.1f, 0f, 1f);

图片绘制和框

图片绘制

1
2
3
4
5
6
7
8
9
public class Lesson4 : MonoBehaviour
{
public Rect texPos;
public Texture texture;
private void OnGUI()
{
GUI.DrawTexture(texPos,texture);
}
}

通过重载可以规定图片的拉伸模式、宽高比和是否开启透明等

框绘制

1
2
3
4
5
6
7
8
public class Lesson4 : MonoBehaviour
{
public Rect texPos;
private void OnGUI()
{
GUI.Box(texPos,"123");
}
}

工具栏和选择网格

工具栏

1
2
3
4
5
6
7
8
9
10
public class Lesson6 : MonoBehaviour
{
public Rect pos;
private int toolbarIndex = 0;
private string[] toolbarInfos ={ "选项1", "选项2", "选项3" };
private void OnGUI()
{
toolbarIndex = GUI.Toolbar(pos, toolbarIndex, toolbarInfos);
}
}

选择网格

1
2
3
4
5
6
7
8
9
10
public class Lesson6 : MonoBehaviour
{
public Rect pos;
private int selGridIndex = 0;
private string[] selGridInfos ={ "选项1", "选项2", "选项3" ,"选项4"};
private void OnGUI()
{
selGridIndex = GUI.SelectionGrid(pos, selGridIndex, selGridInfos, 2);
}
}

滚动视图和分组

分组

分组用于批量控制控件位置,可以理解为控件加了一个父对象

1
2
3
4
5
6
7
8
9
10
public class Lesson7 : MonoBehaviour
{
public Rect pos;
private void OnGUI()
{
GUI.BeginGroup(pos);
GUI.Button(new Rect(0, 0, 100, 50), "测试");
GUI.EndGroup();
}
}

以pos,也就是为左上角锚点,批量控制GUI

滚动列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Lesson7 : MonoBehaviour
{
public Rect scPos,showPos;
private Vector2 nowPos;
private string[] strs = { "132", "321", "123" };
private void OnGUI()
{
nowPos = GUI.BeginScrollView(scPos, nowPos, showPos);
GUI.Toolbar(new Rect(0, 0, 300, 50), 0,strs);
GUI.Toolbar(new Rect(0, 60, 300, 50), 0,strs);
GUI.Toolbar(new Rect(0, 120, 300, 50), 0,strs);
GUI.Toolbar(new Rect(0, 180, 300, 50), 0,strs);
GUI.Toolbar(new Rect(0, 240, 300, 50), 0,strs);
GUI.EndScrollView();
}
}

窗口

窗口

1
2
3
4
5
6
7
8
9
10
11
public class Lesson8 : MonoBehaviour
{
private void OnGUI()
{
GUI.Window(1, new Rect(100, 100, 200, 150), DrawWinddow, "测试窗口");
}
private void DrawWinddow(int id)
{
GUI.Button(new Rect(40, 40, 30, 20),"测试");
}
}

模态窗口

只要模态窗口出现,只能与模态窗口交互,不能和其他UI交互

1
2
3
4
5
6
7
8
9
10
11
public class Lesson8 : MonoBehaviour
{
private void OnGUI()
{
GUI.ModalWindow(2, new Rect(100, 100, 200, 150), DrawWinddow, "测试窗口");
}
private void DrawWinddow(int id)
{
GUI.Button(new Rect(40, 40, 30, 20),"测试");
}
}

拖动窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Lesson8 : MonoBehaviour
{
private Rect dragWinPos = new Rect(400, 400, 200, 150);
private void OnGUI()
{
dragWinPos = GUI.Window(1, dragWinPos, DrawWinddow, "测试窗口");
}
private void DrawWinddow(int id)
{
GUI.Button(new Rect(40, 40, 30, 20),"测试");
if (id == 1)
{
GUI.DragWindow();
}
}
}

自定义皮肤样式

全局颜色

1
2
3
4
5
6
7
8
9
10
public class Lesson6 : MonoBehaviour
{
private void OnGUI()
{
GUI.color = Color.cyan;
GUI.contentColor = Color.red;
GUI.Button(new Rect(100, 100, 100, 30), "测试");
GUI.Label(new Rect(0,50,200,200),"测试");
}
}

整体皮肤样式

1
2
3
4
5
6
7
8
9
10
public class Lesson6 : MonoBehaviour
{
public GUIStyle style;
public GUISkin skin;
private void OnGUI()
{
GUI.skin = skin;
GUI.Button(new Rect(0, 0, 100, 30), "测试");
}
}

如果GUI设置了style,style会覆盖skin的设置

GUILayout自动布局

GUILayout自动布局

1
2
3
4
5
6
7
8
9
public class Lesson6 : MonoBehaviour
{
private void OnGUI()
{
GUILayout.Button("123");
GUILayout.Button("1234");
GUILayout.Button("12345");
}
}

屏幕截图 2023-05-04 164121

自动布局主要用于编辑器开发

也可以自定义一些布局规则

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Lesson6 : MonoBehaviour
{
private void OnGUI()
{
GUI.BeginGroup(new Rect(100,100,100,100));
GUILayout.BeginHorizontal();
GUILayout.Button("123");
GUILayout.Button("1234");
GUILayout.Button("12345");
GUILayout.EndHorizontal();
GUI.EndGroup();
}
}

屏幕截图 2023-05-04 164539

GUILayoutOption布局选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Lesson6 : MonoBehaviour
{
private void OnGUI()
{
GUI.BeginGroup(new Rect(100,100,100,100));
GUILayout.BeginHorizontal();
GUILayout.Button("123");
GUILayout.Button("1234");
GUILayout.Button("12345");
GUILayout.EndHorizontal();
GUI.EndGroup();

// 固定宽高
GUILayout.Width(300);
GUILayout.Height(300);

// 最小宽高
GUILayout.MinHeight(50);
GUILayout.MinWidth(50);

// 最大宽高
// 略
}
}

GUI总结

  • 优点:简单快捷、代码控制
  • 缺点:重复工作量繁多、控制绘制相关代码很多、运行时才能查看结果、不支持分辨率自适应

可以封装一些功能解决GUI的问题