使用GUILayout来定制化高级UI
介绍
GUI和GUILayout都是unity的UI布局类,且都寄托在UnityEngine.IMGUIModule中,所以,我们在使用时,需要从游戏目录中将 UnityEngine.IMGUIModule.dll 引用到我们的项目中来。
其中,
GUI是手动布局,需要我们手动给定x,y,w,h的值;
GUILayout是自动布局,我们只需设置每行排列数量即可;
GUI的布局比较的繁琐,且非常不灵活,所以我比较推荐使用GUILayout来进行UI自动布局;
关于GUILayout的使用与介绍,Unity官网有更加详细的说明,我这边就不做复杂的讲解,大家可以另行见:https://docs.unity3d.com/ScriptReference/GUILayout.html
我这边只做基础的使用方法以及对一些常用的控件进行说明
制作一个窗口
上面说过GUILayout是寄托在UnityEngine.IMGUIModule中的类了,那么,请自行引用UnityEngine.IMGUIModule.dll(在游戏目录 XXX_Data\Managed中)文件到vs工程中。
现在来给大家介绍一个新函数—— OnGUI();
OnGUI()的作用和之前我们介绍的Update()是同类型的,都是在游戏运行后会一直循环执行函数中的内容,不过OnGUI()是unity专门为GUI设定的一个函数,虽然我们窗口写到OnGUI()和写到Update()都可以达到我们想要的效果,但是为了代码更加的规范,我建议大家将UI相关的代码写到OnGUI()中,监听插件相关的代码写到Update()中。
所以,若我们想实现按F9打开/关闭窗口的“开关”,我们可以这样写:
using System;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;
namespace AdvancedUI
{
[BepInPlugin("aoe.top.plugins.AdvancedUI", "高级UI示例", "1.0.0.0")]
public class AdvancedUI : BaseUnityPlugin
{
// 窗口开关
public bool DisplayingWindow = false;
// 启动按键
private ConfigEntry ShowCounter { get; set; }
[Obsolete]
public void Start()
{
// 允许用户自定义启动快捷键
ShowCounter = Config.AddSetting("打开窗口快捷键", "Key", new BepInEx.Configuration.KeyboardShortcut(KeyCode.F9));
}
public void Update()
{
// 监听脚本按键按下
if (ShowCounter.Value.IsDown())
{
DisplayingWindow = !DisplayingWindow;
if (DisplayingWindow)
{
Debug.Log("打开窗口");
}
else
{
Debug.Log("关闭窗口");
}
}
}
// GUI函数
private void OnGUI()
{
if (this.DisplayingWindow)
{
// 定义窗口位置 x y 宽 高
Rect windowRect = new Rect(500, 200, 500, 300);
// 创建一个新窗口
// 注意:第一个参数(20210218)为窗口ID,ID尽量设置的与众不同,若与其他Mod的窗口ID相同,将会导致窗口冲突
windowRect = GUI.Window(20210218, windowRect, DoMyWindow, "我的一个窗口");
}
}
public void DoMyWindow(int winId)
{
}
}
}
以上代码即可简单实现按F9打开/关闭窗口:
自动UI布局
定义新的区域:GUILayout.BeginArea
默认,GUILayout都是从左上角0,0坐标开始进行自动布局的,有时候,我们希望它显示在窗口中的其他位置,我们则需要使用GUILayout.BeginArea来定义一个新的区域,然后再将我们的控件写进去。
注意:GUILayout.BeginArea需要搭配 GUILayout.EndArea一起使用,否则会报错。
示例:
public void DoMyWindow(int winId)
{
GUILayout.BeginArea(new Rect(10, 20, 490, 250));
// 这里的大括号是可选的,我个人为了代码的阅读性,习惯性的进行了添加
// 建议大家也使用大括号这样包裹起来,让代码看起来不那么的乱
{
GUILayout.Label("这是一行普通的文本框");
if (GUILayout.Button("按钮1"))
{
Debug.Log("你点击了按钮1");
}
if (GUILayout.Button("按钮2"))
{
Debug.Log("你点击了按钮2");
}
}
GUILayout.EndArea();
}
运行结果:
横向自动布局:GUILayout.BeginHorizontal
默认,GUILayout是竖向自动排列的,但我们可以使用GUILayout.BeginHorizontal让我们的控件进行横向排列。
注意:GUILayout.BeginHorizontal需要与GUILayout.EndHorizontal配合使用,否则会报错。
示例:
public void DoMyWindow(int winId)
{
GUILayout.BeginArea(new Rect(10, 20, 480, 250));
{
GUILayout.Label("这是一行普通的文本框");
// 第一行
GUILayout.BeginHorizontal();
{
if (GUILayout.Button("按钮1.1"))
{
Debug.Log("你点击了按钮1.1");
}
if (GUILayout.Button("按钮1.2"))
{
Debug.Log("你点击了按钮1.2");
}
if (GUILayout.Button("按钮1.3"))
{
Debug.Log("你点击了按钮1.3");
}
if (GUILayout.Button("按钮1.4"))
{
Debug.Log("你点击了按钮1.4");
}
}
GUILayout.EndHorizontal();
// 第二行
GUILayout.BeginHorizontal();
{
if (GUILayout.Button("按钮2.1"))
{
Debug.Log("你点击了按钮2.1");
}
if (GUILayout.Button("按钮2.2"))
{
Debug.Log("你点击了按钮2.2");
}
if (GUILayout.Button("按钮2.3"))
{
Debug.Log("你点击了按钮2.3");
}
if (GUILayout.Button("按钮2.4"))
{
Debug.Log("你点击了按钮2.4");
}
}
GUILayout.EndHorizontal();
}
GUILayout.EndArea();
}
运行结果:
窗口滚动条:GUILayout.BeginScrollView
若我们的内容太多,又不想制作分页,那么就可能需要用到滚动条了,滚动条需要定义一个全局 Vector2 变量来接收、传递、储存滚动条的x,y坐标位置;
注意:GUILayout.BeginScrollView需与GUILayout.EndHorizontal配合使用,否则会报错
示例:
private Vector2 scrollPosition;
public void DoMyWindow(int winId)
{
GUILayout.BeginArea(new Rect(10, 20, 480, 250));
{
GUILayout.Label("这是一行普通的文本框");
// 第一行
GUILayout.BeginHorizontal();
{
if (GUILayout.Button("按钮1.1"))
{
Debug.Log("你点击了按钮1.1");
}
if (GUILayout.Button("按钮1.2"))
{
Debug.Log("你点击了按钮1.2");
}
if (GUILayout.Button("按钮1.3"))
{
Debug.Log("你点击了按钮1.3");
}
if (GUILayout.Button("按钮1.4"))
{
Debug.Log("你点击了按钮1.4");
}
}
GUILayout.EndHorizontal();
// 第二行
GUILayout.BeginHorizontal();
{
if (GUILayout.Button("按钮2.1"))
{
Debug.Log("你点击了按钮2.1");
}
if (GUILayout.Button("按钮2.2"))
{
Debug.Log("你点击了按钮2.2");
}
if (GUILayout.Button("按钮2.3"))
{
Debug.Log("你点击了按钮2.3");
}
if (GUILayout.Button("按钮2.4"))
{
Debug.Log("你点击了按钮2.4");
}
}
GUILayout.EndHorizontal();
// 滚动条区域
scrollPosition = GUILayout.BeginScrollView(scrollPosition, false, false, GUILayout.Width(480), GUILayout.Height(150));
{
if (GUILayout.Button("按钮3"))
{
Debug.Log("你点击了按钮3");
}
if (GUILayout.Button("按钮4"))
{
Debug.Log("你点击了按钮4");
}
if (GUILayout.Button("按钮5"))
{
Debug.Log("你点击了按钮5");
}
if (GUILayout.Button("按钮6"))
{
Debug.Log("你点击了按钮6");
}
if (GUILayout.Button("按钮7"))
{
Debug.Log("你点击了按钮7");
}
if (GUILayout.Button("按钮8"))
{
Debug.Log("你点击了按钮8");
}
if (GUILayout.Button("按钮9"))
{
Debug.Log("你点击了按钮9");
}
if (GUILayout.Button("按钮10"))
{
Debug.Log("你点击了按钮10");
}
}
GUILayout.EndScrollView();
}
GUILayout.EndArea();
}
运行结果: