GUI基础
一、GUI是什么
GUI主要作用
GUI工作原理
二、重要参数、文本、按钮
所有GUI相关步骤都必须写在OnGUI函数中。
文本控件
传入Rect参数可以控制尺寸,Texture控制图片。两种想要一起控制需要用综合控制,需要传入GUIContent。
传入参数GUIStyle,并设置为public可以在unity界面看见。
按钮
与文本控件类似,但他的显示需要设置多个图片才能有后续点击和接触变换。
上图中Button方法是创建一个按钮并提供一次点击检测,而RepeatButton是长按点击。
Style:是管理风格的,传入参数并将参数设置为public可以在unity进行设置。
练习题:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GUITest : MonoBehaviour
{
public Rect rect1;
public GUIContent gct1;
public Rect rect2;
public Rect rect3;
public GUIContent gct2;
public GUIContent gct3;
private void OnGUI()
{
if (GUI.Button(rect1, gct1))
{
SceneManager.LoadScene("SampleScene");
}
GUI.Button(rect2, gct2);
if (GUI.Button(rect3, gct3))
{
print("关闭游戏");
//预处理#if,UNITY_EDITOR 是 Unity 定义的 编译符号(Preprocessor Symbol),用于区分代码是在 Unity 编辑器 里运行,还是在 打包后的游戏 里运行。
#if UNITY_EDITOR
EditorApplication.isPlaying = false; // 在编辑器里停止播放
#else
Application.Quit(); // 在打包后的游戏里退出
#endif
}
}
}
三、多选和单选框
多选框
该方法参数需要传入位置信息,方法返回值是点击一次更换一次,所以能够相互切换,后面是按钮的文字。
加入GUIStyle参数之后,可以去调整他的图片宽高,因为Rect影响响应区域和整体字体大小,而该fixedWidth和fixedHeight是修改图片大小,而padding是管理图片到文字的偏移量。
单选框
判断是否点选了当前按钮,点选后就会设置变量为对应值,下一帧更新就会变换选中状态。
练习题:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GUITest : MonoBehaviour
{
public Rect rect1;
public GUIContent gct1;
public Rect rect2;
public Rect rect3;
public GUIContent gct2;
public GUIContent gct3;
public Rect boxRect;
public Rect rect4;
public GUIStyle boxStyle;
private bool isCreate = false;
private int isMusic = 1;
private int isSound = 1;
private void OnGUI()
{
GUI.enabled = !isCreate;
if (GUI.Button(rect1, gct1))
{
SceneManager.LoadScene("SampleScene");
}
if(GUI.Button(rect2, gct2))
{
print(Screen.width);
print(Screen.height);
isCreate = true;
}
if (GUI.Button(rect3, gct3))
{
print("关闭游戏");
//预处理#if,UNITY_EDITOR 是 Unity 定义的 编译符号(Preprocessor Symbol),用于区分代码是在 Unity 编辑器 里运行,还是在 打包后的游戏 里运行。
#if UNITY_EDITOR
EditorApplication.isPlaying = false; // 在编辑器里停止播放
#else
Application.Quit(); // 在打包后的游戏里退出
#endif
}
GUI.enabled = true;
if (isCreate)
{
GUI.Box(boxRect, "设置面板", boxStyle);
if (GUI.Button(rect4, "关闭"))
{
isCreate = false;
}
GUI.Label(new Rect(100, 120, 100, 20), "音乐");
if (GUI.Toggle(new Rect(150, 120, 100, 20), isMusic == 1, "开启"))
{
isMusic = 1;
}
if (GUI.Toggle(new Rect(260, 120, 100, 20), isMusic == 2, "关闭"))
{
isMusic = 2;
}
GUI.Label(new Rect(100, 170, 100, 20), "音效");
if (GUI.Toggle(new Rect(150, 170, 100, 20), isSound == 1, "开启"))
{
isSound = 1;
}
if (GUI.Toggle(new Rect(260, 170, 100, 20), isSound == 2, "关闭"))
{
isSound = 2;
}
}
}
}
四、输入框和拖动条
普通输入框
通过在OnGUI方法外声明string字符串,之后利用TextField返回值为输入值的特点,再将返回值赋值给inputStr。之后还能在第三个参数设置输入值最大长度。
密码输入框
同样的,需要事先声明string变量在OnGUI外。第三个参数为控制隐藏后显示占位的符号。
拖动条
英语生词:Slider:滑块;Horizontal:水平的;Vertical:垂直的;
最后两个参数是最小值和最大值。
练习题:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GUITest : MonoBehaviour
{
public Rect rect1;
public GUIContent gct1;
public Rect rect2;
public Rect rect3;
public GUIContent gct2;
public GUIContent gct3;
public Rect boxRect;
public Rect rect4;
public GUIStyle boxStyle;
//是否创建
private bool isCreateSet = false;
private bool isCreateSignIn = false;
private int isMusic = 1;
private int isSound = 1;
public Rect textureRect;
public Texture texture;
public ScaleMode mode;
public bool isAlpha;
private float nowValue;
private string inputStr = "";
private string inputStr1 = "";
private void OnGUI()
{
GUI.enabled = !isCreateSet && !isCreateSignIn;
if (GUI.Button(rect1, gct1))
{
isCreateSignIn = true;
}
if(GUI.Button(rect2, gct2))
{
print(Screen.width);
print(Screen.height);
isCreateSet = true;
}
if (GUI.Button(rect3, gct3))
{
print("关闭游戏");
//预处理#if,UNITY_EDITOR 是 Unity 定义的 编译符号(Preprocessor Symbol),用于区分代码是在 Unity 编辑器 里运行,还是在 打包后的游戏 里运行。
#if UNITY_EDITOR
EditorApplication.isPlaying = false; // 在编辑器里停止播放
#else
Application.Quit(); // 在打包后的游戏里退出
#endif
}
GUI.enabled = true;
if (isCreateSet)
{
GUI.Box(boxRect, "设置面板", boxStyle);
if (GUI.Button(rect4, "关闭"))
{
isCreateSet = false;
}
GUI.Label(new Rect(100, 120, 100, 20), "音乐");
if (GUI.Toggle(new Rect(150, 120, 100, 20), isMusic == 1, "开启"))
{
isMusic = 1;
}
if (GUI.Toggle(new Rect(260, 120, 100, 20), isMusic == 2, "关闭"))
{
isMusic = 2;
}
//拖动条
nowValue = GUI.HorizontalSlider(new Rect(380, 120, 100, 20), nowValue, 0, 1);
//音量显示
GUI.Box(new Rect(500, 120, 100, 20), $"{nowValue * 100}");
GUI.Label(new Rect(100, 170, 100, 20), "音效");
if (GUI.Toggle(new Rect(150, 170, 100, 20), isSound == 1, "开启"))
{
isSound = 1;
}
if (GUI.Toggle(new Rect(260, 170, 100, 20), isSound == 2, "关闭"))
{
isSound = 2;
}
}
if (isCreateSignIn)
{
GUI.Box(new Rect(250, 50, 450, 300), "登录", boxStyle);
if (GUI.Button(rect4, "关闭"))
{
isCreateSignIn = false;
}
GUI.Label(new Rect(320, 120, 50, 20), "用户名");
inputStr = GUI.TextField(new Rect(370, 120, 120, 20), inputStr, 7);
GUI.Label(new Rect(320, 150, 50, 20), "密 码");
inputStr1 = GUI.TextField(new Rect(370, 150, 120, 20), inputStr1, 7);
if(GUI.Button(new Rect(350, 200, 100, 60), "登 录"))
{
if (inputStr == "admin" && inputStr1 == "123")
{
SceneManager.LoadScene("SampleScene");
}
else
{
print("密码错误");
}
}
}
}
}
五、图片绘制和框
图片绘制
参数:1、位置和大小;2、图片;3、模式,控制图片适应宽高的模式;4、开启透明;5、宽高比;
框绘制
练习题:
六、工具栏和选择网格
工具栏
选择网格
选择网格比工具栏多了一个控制一行有几个按钮。
七、滚动列表和分组
分组
相当于加了一个父类,来控制整体的位置和大小。
滚动列表
第一个参数用于控制当前可见范围的Rect,第二个参数是控制当前显示位置的Vector2类型,第三个为整体内容的Rect,其中的位置是显示区域偏移一般为0,0。
练习题:
public string[] labelStr;
private Vector2 viewPos;
private void OnGUI()
{
viewPos = GUI.BeginScrollView(new Rect(0,0, 100, 100), viewPos, new Rect(0,0,200, 50*labelStr.Length));
for (int i = 0; i < labelStr.Length; i++)
{
GUI.Label(new Rect(0, i * 50, 100, 30), labelStr[i]);
}
GUI.EndScrollView();
}
八、窗口
普通窗口
需要特别注意id是用来唯一的。可以通过第三个参数设置函数处理不同逻辑。
模态窗口
拖动窗口
拖动窗口需要在函数中添加GUI.DragWindow才能拖动。
练习题:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GUITest : MonoBehaviour
{
public Rect rect1;
public GUIContent gct1;
public Rect rect2;
public Rect rect3;
public GUIContent gct2;
public GUIContent gct3;
public Rect boxRect;
public Rect rect4;
public GUIStyle boxStyle;
//是否创建
private bool isCreateSet = false;
private bool isCreateSignIn = false;
private bool isCreateEsc = false;
private int isMusic = 1;
private int isSound = 1;
public Rect textureRect;
public Texture texture;
public ScaleMode mode;
public bool isAlpha;
private float nowValue;
private Rect dragWindowPos = new Rect(250, 50, 570, 300);
private string inputStr = "";
private string inputStr1 = "";
private void OnGUI()
{
GUI.enabled = !isCreateSet && !isCreateSignIn;
if (GUI.Button(rect1, gct1))
{
isCreateSignIn = true;
}
if (GUI.Button(rect2, gct2))
{
print(Screen.width);
print(Screen.height);
isCreateSet = true;
}
if (GUI.Button(rect3, gct3))
{
isCreateEsc = true;
}
GUI.enabled = true;
if (isCreateSet)
{
GUI.Box(boxRect, "设置面板", boxStyle);
if (GUI.Button(rect4, "关闭"))
{
isCreateSet = false;
}
GUI.Label(new Rect(100, 120, 100, 20), "音乐");
if (GUI.Toggle(new Rect(150, 120, 100, 20), isMusic == 1, "开启"))
{
isMusic = 1;
}
if (GUI.Toggle(new Rect(260, 120, 100, 20), isMusic == 2, "关闭"))
{
isMusic = 2;
}
//拖动条
nowValue = GUI.HorizontalSlider(new Rect(380, 120, 100, 20), nowValue, 0, 1);
//音量显示
GUI.Box(new Rect(500, 120, 100, 20), $"{nowValue * 100}");
GUI.Label(new Rect(100, 170, 100, 20), "音效");
if (GUI.Toggle(new Rect(150, 170, 100, 20), isSound == 1, "开启"))
{
isSound = 1;
}
if (GUI.Toggle(new Rect(260, 170, 100, 20), isSound == 2, "关闭"))
{
isSound = 2;
}
}
if (isCreateSignIn)
{
GUI.Box(new Rect(250, 50, 450, 300), "登录", boxStyle);
if (GUI.Button(rect4, "关闭"))
{
isCreateSignIn = false;
}
GUI.Label(new Rect(320, 120, 50, 20), "用户名");
inputStr = GUI.TextField(new Rect(370, 120, 120, 20), inputStr, 7);
GUI.Label(new Rect(320, 150, 50, 20), "密 码");
inputStr1 = GUI.TextField(new Rect(370, 150, 120, 20), inputStr1, 7);
if (GUI.Button(new Rect(350, 200, 100, 60), "登 录"))
{
if (inputStr == "admin" && inputStr1 == "123")
{
SceneManager.LoadScene("SampleScene");
}
else
{
print("密码错误");
}
}
}
if (isCreateEsc)
{
dragWindowPos = GUI.ModalWindow(1, dragWindowPos, Fun1, "关闭面板");
}
}
private void Fun1(int id)
{
GUI.DragWindow(new Rect(0, 0, 400, 20));
if (GUI.Button(new Rect(50, 150, 100, 30), "取消"))
{
isCreateEsc = false;
}
if (GUI.Button(new Rect(330, 150, 100, 30), "关闭"))
{
print("关闭游戏");
//预处理#if,UNITY_EDITOR 是 Unity 定义的 编译符号(Preprocessor Symbol),用于区分代码是在 Unity 编辑器 里运行,还是在 打包后的游戏 里运行。
#if UNITY_EDITOR
EditorApplication.isPlaying = false; // 在编辑器里停止播放
#else
Application.Quit(); // 在打包后的游戏里退出
#endif
}
}
}
九、自定义皮肤样式
全局颜色
可以更改全局颜色、背景、字体颜色。但注意全局和其他颜色会相乘。
自定义皮肤
可以在脚本中声明一个public类型的GUISkin,再在unity中创建GUISkin或者中文下的GUI蒙皮。设置想改变的内容并拖入unity脚本组件相应的位置。
十、GUILayout自动布局
自动布局
自动布局可以设置为横向排列。
GUILayout布局选项
可以在自动布局的按钮或其他的括号里面加上上图的选项。
实践
[ExecuteAlways]:非运行状态下更新
九宫格位置计算
相对屏幕位置:相对于屏幕原点的位置,每次计算需要加上;中心点偏移位置:控件本身中心点变化的偏移量;偏移位置:相对于每一个小区域的偏移量。