Unity-GUI

96 阅读6分钟

GUI基础

一、GUI是什么

image.png

GUI主要作用

image.png

GUI工作原理

image.png

二、重要参数、文本、按钮

所有GUI相关步骤都必须写在OnGUI函数中。

image.png

文本控件

传入Rect参数可以控制尺寸,Texture控制图片。两种想要一起控制需要用综合控制,需要传入GUIContent。

image.png

传入参数GUIStyle,并设置为public可以在unity界面看见。

image.png

按钮

与文本控件类似,但他的显示需要设置多个图片才能有后续点击和接触变换。

image.png

上图中Button方法是创建一个按钮并提供一次点击检测,而RepeatButton是长按点击。

Style:是管理风格的,传入参数并将参数设置为public可以在unity进行设置。

练习题:

image.png

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
        }
    }

}

三、多选和单选框

多选框

image.png

该方法参数需要传入位置信息,方法返回值是点击一次更换一次,所以能够相互切换,后面是按钮的文字。

image.png

加入GUIStyle参数之后,可以去调整他的图片宽高,因为Rect影响响应区域和整体字体大小,而该fixedWidth和fixedHeight是修改图片大小,而padding是管理图片到文字的偏移量。

单选框

image.png

判断是否点选了当前按钮,点选后就会设置变量为对应值,下一帧更新就会变换选中状态。

练习题:

image.png

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;
            }
        }
    }

}

四、输入框和拖动条

普通输入框

image.png

通过在OnGUI方法外声明string字符串,之后利用TextField返回值为输入值的特点,再将返回值赋值给inputStr。之后还能在第三个参数设置输入值最大长度。

密码输入框

image.png

同样的,需要事先声明string变量在OnGUI外。第三个参数为控制隐藏后显示占位的符号。

拖动条

英语生词:Slider:滑块;Horizontal:水平的;Vertical:垂直的;

image.png

image.png

最后两个参数是最小值和最大值。

练习题:

image.png

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("密码错误");
                }
            }
        }
    }

}

五、图片绘制和框

图片绘制

image.png

参数:1、位置和大小;2、图片;3、模式,控制图片适应宽高的模式;4、开启透明;5、宽高比;

框绘制

image.png

练习题:

image.png

六、工具栏和选择网格

工具栏

image.png

选择网格

image.png

选择网格比工具栏多了一个控制一行有几个按钮。

七、滚动列表和分组

分组

image.png

相当于加了一个父类,来控制整体的位置和大小。

滚动列表

image.png

第一个参数用于控制当前可见范围的Rect,第二个参数是控制当前显示位置的Vector2类型,第三个为整体内容的Rect,其中的位置是显示区域偏移一般为0,0。

练习题:

image.png

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();
}

八、窗口

普通窗口

image.png

需要特别注意id是用来唯一的。可以通过第三个参数设置函数处理不同逻辑。

模态窗口

image.png

拖动窗口

image.png

拖动窗口需要在函数中添加GUI.DragWindow才能拖动。

image.png

练习题:

image.png

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
        }
    }
}

九、自定义皮肤样式

全局颜色

image.png

可以更改全局颜色、背景、字体颜色。但注意全局和其他颜色会相乘。

自定义皮肤

image.png

可以在脚本中声明一个public类型的GUISkin,再在unity中创建GUISkin或者中文下的GUI蒙皮。设置想改变的内容并拖入unity脚本组件相应的位置。

十、GUILayout自动布局

自动布局

image.png

自动布局可以设置为横向排列。

GUILayout布局选项

image.png

可以在自动布局的按钮或其他的括号里面加上上图的选项。

实践

[ExecuteAlways]:非运行状态下更新

九宫格位置计算

image.png

相对屏幕位置:相对于屏幕原点的位置,每次计算需要加上;中心点偏移位置:控件本身中心点变化的偏移量;偏移位置:相对于每一个小区域的偏移量。

image.png