UnityUI-IMGUI

  1. 1. 一、 工作原理和主要作用
  2. 2. 二、文本和按钮控件
  3. 3. 三、多选框和单选框
  4. 4. 四、输入框和拖动条(滑动条slider)
  5. 5. 五、图片绘制和框
  6. 6. 六、工具栏和选择网格
  7. 7. 七、滚动列表和分组
  8. 8. 八、窗口
  9. 9. 九、自定义皮肤样式
  10. 10. 十、自动布局

 

一、 工作原理和主要作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using UnityEngine;

public class GUIStudy : MonoBehaviour
{
#region GUI是什么
// 全称:即时模式游戏用户交互界面(IMGUI)
// 在unity中一般简称为GUI
// 它是一个代码驱动的UI系统
#endregion

#region GUI的主要作用
// 作为程序员的调试工具,创建游戏内调试工具
// 为脚本组件创建自定义检视面板
// 创建新的编辑器窗口和工具以拓展Unity本身(一般用作内置游戏工具)

// 注意:不要用它为玩家制作UI功能
#endregion

#region GUI的工作原理
// 在继承MonoBehaviour的脚本中的特殊函数里
// 调用GUI提供的方法
// 类似生命周期函数
private void OnGUI()
{
// 在其中书写 GUI相关代码 即可显示GUI内内容
}
// 注意:
// 它每帧执行 相当于是用于专门绘制GUI界面的函数
// 一般只用在其中执行GUI相关界面绘制和操作逻辑
// 该函数在 OnDisable之前 LateUpdate之后 执行
// 只要是继承Mono的脚本 都可以在OnGUI中绘制GUI
#endregion
}

二、文本和按钮控件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using UnityEngine;

public class GUIStudy2 : MonoBehaviour
{
[SerializeField] private Texture tex;
[SerializeField] private Rect rect;

[SerializeField] private Rect rect1;
[SerializeField] private GUIContent content;

[SerializeField] private GUIStyle style;

[SerializeField] private Rect btnRect;
[SerializeField] private GUIContent btnContent;
[SerializeField] private GUIStyle btnStyle;

private void OnGUI()
{
#region GUI 控件绘制的共同点
// 1.它们都是GUI公共类中提供的静态函数
// 2.它们的参数都大同小异
// 位置参数:Rect参数 x y位置 w h尺寸
// 显示文本:string参数
// 图片信息:Texture参数
// 综合信息:GUIContent参数
// 自定义样式:GUIStyle参数
// 3.每一种控件都有多种重载,都是各个参数的排列组合
// 必备的参数内容 是 位置信息和显示信息
#endregion

#region 文本控件
// 基本使用
GUI.Label(new Rect(0, 0, 100, 20), "HelloWorld"); // 每帧new,性能消耗大
GUI.Label(rect, tex);
// 综合使用
GUI.Label(rect1, content);
// 可以获取当前鼠标或者键盘选中的GUI控件 对应的tooltip信息
// Debug.Log(GUI.tooltip);
// 自定义样式
GUI.Label(new Rect(0, 100, 100, 40), "HelloWorld_style", style);
#endregion

#region 按钮控件
//if (GUI.Button(btnRect, btnContent, btnStyle))
//{
// Debug.Log("按钮被点击");
//}

if (GUI.RepeatButton(btnRect, btnContent, btnStyle))
{
Debug.Log("长按按钮被点击");
}
#endregion
}
private void Start()
{

}
}


三、多选框和单选框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using UnityEngine;

public class GUIStudy3 : MonoBehaviour
{
[SerializeField] private bool isSel;
[SerializeField] private bool isSel2;
[SerializeField] private GUIStyle style;

private int nowSelIndex = 1;

private void OnGUI()
{
isSel = GUI.Toggle(new Rect(0, 0, 10, 10), isSel, "toggle");
isSel2 = GUI.Toggle(new Rect(0, 40, 100, 30), isSel2, "toggle2", style);

// 单选框
if (GUI.Toggle(new Rect(100, 100, 20, 20), nowSelIndex == 1, "sel1"))
{
nowSelIndex = 1;
}
if (GUI.Toggle(new Rect(100, 140, 20, 20), nowSelIndex == 2, "sel2"))
{
nowSelIndex = 2;
}
if (GUI.Toggle(new Rect(100, 180, 20, 20), nowSelIndex == 3, "sel3"))
{
nowSelIndex = 3;
}

}
void Start()
{

}
}


四、输入框和拖动条(滑动条slider)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using UnityEngine;

public class GUIStudy4 : MonoBehaviour
{
private string inputStr = "";
private string inputPw = "";

[SerializeField] private float nowValue = .5f;

private void OnGUI()
{
#region 输入框
// 分为 ; 普通输入、密码输入
// 区别是,在输入密码时,让用户看不见具体输入的内容

// 普通输入
// 重要参数 : 一个是显示内容 string , 一个是最大输入字符串的长度
inputStr = GUI.TextField(new Rect(0, 0, 100, 30), inputStr, 5);
//inputStr = GUI.TextField(new Rect(0, 0, 100, 30), inputStr);

// 密码输入
// 第三参数可以填任意符合
inputPw = GUI.PasswordField(new Rect(0, 50, 100, 30), inputPw, '*');
#endregion

#region 拖动条
// 当前值、最小值left、最大值right
nowValue = GUI.HorizontalSlider(new Rect(0, 100, 100, 50), nowValue, 0, 1);
// GUI.VerticalSlider
#endregion
}

private void Start()
{

}
}


五、图片绘制和框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using UnityEngine;

public class GUIStudy5 : MonoBehaviour
{
[SerializeField] private Rect texPos;
[SerializeField] private Texture img;
// 缩放模式ScaleMode
// ScaleAndCrop : 会自动根据宽高比进行计算,但是,会进行裁剪
// ScaleToFit : 会自动根据宽高比进行计算,不会拉变形,会一直保持图片完全显示的状态 (最常用)
// StretchToFill : 始终填充满传入的Rect范围 (默认)
[SerializeField] private ScaleMode scaleMode = ScaleMode.StretchToFill;
// alpha
// 是用来控制图片是否开启 透明通道 的
[SerializeField] private bool alpha = true;
// imageAspect : 自定义宽高比,如果不填,默认为0,就会使用图片原始宽高
[SerializeField] private float wh = 0;


private void OnGUI()
{
#region 图片绘制
GUI.DrawTexture(texPos, img, scaleMode, alpha, wh);
#endregion

#region 框绘制
GUI.Box(texPos, "123");
#endregion
}


void Start()
{

}
}


六、工具栏和选择网格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using UnityEngine;

public class GUIStudy6 : MonoBehaviour
{
private int toolbarIndex = 0;
private string[] toolbarInfos = new string[] { "选项一", "选项二", "选项三" };

private int selGridIndex = 0;

void OnGUI()
{
#region 工具栏
toolbarIndex = GUI.Toolbar(new Rect(0, 0, 200, 30), toolbarIndex, toolbarInfos);
// 工具栏可以根据不同的返回索引,来处理不同的逻辑
switch (toolbarIndex)
{
case 0:
break;
case 1:
break;
case 2:
break;
}
#endregion

#region 选择网格
// 相对toolbar多了一个参数 xCount 代表 水平方向最多显示的按钮数量 超过时会换行显示
selGridIndex = GUI.SelectionGrid(new Rect(0, 50, 200, 60), selGridIndex, toolbarInfos, 2);
#endregion
}

void Start()
{

}
}


七、滚动列表和分组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using UnityEngine;

public class GUIStudy7 : MonoBehaviour
{
[SerializeField] Rect groupPos;

[SerializeField] Rect scPos;
[SerializeField] Rect showPos;
private Vector2 nowPos;

private string[] toolbarInfos = new string[] { "选项一", "选项二", "选项三", "选项四"};

private void OnGUI()
{
#region 分组
// 用于批量控制控件位置
// 可以理解为 包裹着的控件加了一个父对象
// 可以通过控件分组来控制包裹控件的位置

// 包裹位置以传入的位置为左上角原点
GUI.BeginGroup(groupPos);
GUI.Button(new Rect(0, 0, 100, 50), "testBtn");
GUI.Label(new Rect(0, 60, 100, 20), "testLabel");
GUI.EndGroup();
#endregion

#region 滚动列表
// scPos可见范围大小 showPos内容大小
nowPos = GUI.BeginScrollView(scPos, nowPos, showPos);
GUI.Toolbar(new Rect(0, 0, 300, 50), 0, toolbarInfos);
GUI.Toolbar(new Rect(0, 60, 300, 50), 0, toolbarInfos);
GUI.Toolbar(new Rect(0, 120, 300, 50), 0, toolbarInfos);
GUI.Toolbar(new Rect(0, 180, 300, 50), 0, toolbarInfos);
GUI.EndScrollView();
#endregion
}
private void Start()
{

}
}


八、窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using UnityEngine;

public class GUIStudy8 : MonoBehaviour
{

private Rect dragWindowPos = new Rect(400, 200, 200, 150);
void OnGUI()
{
#region 窗口 基本使用
// 第一个参数 id 是窗口的唯一ID 不要和别的窗口重复
// id有一个重要的作用,除了区分不同窗口,还可以在一个函数中去处理多个窗口的逻辑
// 委托函数 绘制窗口用的函数 传入即可
GUI.Window(1, new Rect(100, 100, 200, 150), DrawWindow, "TestWindow");
GUI.Window(2, new Rect(100, 300, 200, 150), DrawWindow, "TestWindow2");
#endregion

#region 模态窗口
// 可以让其他控件不再有用
// 可以理解为 该窗口在最上层 其他按钮都点击不到了
// 只能点击该窗口上的控件

// GUI.ModalWindow(3, new Rect(300, 100, 200, 150), DrawWindow, "模态窗口");

#endregion

#region 拖动窗口
dragWindowPos = GUI.Window(4, dragWindowPos, DrawWindow, "拖动窗口");

#endregion
}

private void DrawWindow(int id)
{
switch (id)
{
case 1:
GUI.Button(new Rect(10, 30, 30, 20), "1");
break;
case 2:
GUI.Button(new Rect(10, 30, 30, 20), "2");
break;
case 3:
GUI.Button(new Rect(10, 30, 30, 20), "3");
break;
case 4:
GUI.Button(new Rect(10, 30, 30, 20), "4");
// 该API 写在窗口函数中调用 可以让窗口被拖动
// 传入Rect参数的重载 作用
// 是决定窗口中哪一部分位置 可以被拖动 超出窗口部分不算
// 默认不填 就是无参重载 默认窗口的所有位置都能被拖动
GUI.DragWindow(new Rect(0, 0, 1000, 20));
break;
}

}

void Start()
{

}
}


九、自定义皮肤样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using UnityEngine;

public class GUIStudy9 : MonoBehaviour
{
[SerializeField] private GUIStyle style;
[SerializeField] private GUISkin skin;
private void OnGUI()
{
#region 全局颜色
// 全局的着色颜色,影响背景和文本颜色
// GUI.color = Color.red;
// 文本着色颜色
//GUI.contentColor = Color.yellow; // 会与全局颜色做乘法
//GUI.Button(new Rect(0, 0, 100, 30), "测试按钮");
//GUI.backgroundColor = Color.red; // 会与全局颜色做乘法
//GUI.Label(new Rect(0, 50, 100, 30), "测试标签");
//GUI.color = Color.white;
//GUI.Button(new Rect(0, 100, 100, 30), "测试按钮", style);

#endregion

#region 整体皮肤样式
//GUI.skin = null;
GUI.skin = skin;

GUI.Button(new Rect(0, 0, 100, 30), "测试按钮");
#endregion
}
void Start()
{

}
}


十、自动布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using UnityEngine;

public class GUIStudy10 : MonoBehaviour
{

private void OnGUI()
{
#region 自动布局
// 主要用于进行编辑器开发 如果用它来做游戏UI不太合适
// 可以与GUI配合使用
GUI.BeginGroup(new Rect(100, 100, 100, 100));
GUILayout.BeginHorizontal();

GUILayout.Button("123", GUILayout.Width(50));
GUILayout.Button("123465");
GUILayout.Button("1234", GUILayout.ExpandWidth(false)); // 关闭后不会与最长元素对齐

GUILayout.EndHorizontal();
GUI.EndGroup();
#endregion

#region GUILayoutOption 布局选项
// 控件的固定宽高
GUILayout.Width(300);
GUILayout.Height(200);
// 允许控件的最小宽高
GUILayout.MinWidth(50);
GUILayout.MinHeight(50);
// 允许控件的最大宽高
GUILayout.MaxWidth(100);
GUILayout.MaxHeight(100);
// 允许或禁止水平拓展
GUILayout.ExpandWidth(true); // 允许
GUILayout.ExpandWidth(false); // 禁止
GUILayout.ExpandHeight(true); // 允许
GUILayout.ExpandHeight(false); // 禁止
#endregion
}
private void Start()
{

}
}


IMGUI学习结束!