(Unity GUI(IMGUI)系统(一))


前言

我接触unity的时候,unity已经出到5.3版本以后了,所以我一开始接触的UI系统是unity新出不久的UGUI系统。听前辈说,他们之前开发游戏都是用的GUI,然而当时的GUI写起来麻烦而且也不好实现一些复杂的UI效果,所以就用的NGUI来开发游戏界面了。我随后也学习了一下NGUI,使用效果和UGUI很相似。自此我一直以为GUI系统被淘汰了,知道我接触到unity工具开发,才发现我还是年轻,只好滚来好好学习一下GUI,等写完这个我就去写编辑器扩展。


一、简介

GUI 系统(也称为 IMGUI)是一个完全独立的功能系统,不同于 Unity 基于游戏对象的主 UI 系统。IMGUI 是一个代码运行的 GUI 系统,主要用作程序员的工具。为了运行该系统,需在实现脚本上调用 OnGUI 函数。
例如,以下代码:

void OnGUI() {
            if (GUILayout.Button("Press Me"))
                Debug.Log("Hello!");
        }

运行:
在这里插入图片描述

其控件放置规则是以左上角为(0,0)点进行计算的。

GUI坐标图:
在这里插入图片描述
图片来源: https://img-blog.csdn.net/20131221215144906.

实时模式 GUI 系统常用于:

(1)创建游戏内调试显示和工具。
(2)为脚本组件创建自定义检视面板。
(3)创建新的编辑器窗口和工具以扩展 Unity 本身。
(4)IMGUI 系统通常不适合用于玩家可能使用和交互的普通游戏内用户界面。对于此类用途,应使用 Unity 基于游戏对象的主 UI 系统(UGUI),因为其提供了基于游戏对象的编辑和定位 UI 元素的方法,并有更好的工具可用于处理 UI 的可视化设计和布局。

“实时模式”指的是创建和绘制 IMGUI 的方式。要创建 IMGUI 元素,必须编写进入名为 OnGUI 的特殊函数的代码。显示界面的代码将在每帧执行,并绘制到屏幕上。除了 OnGUI 代码附加到的对象,或者层级视图中与绘制的可视元素相关的其他类型对象之外,没有其他持久性游戏对象。

IMGUI 允许使用代码创建各种功能 GUI。通过该系统,无需创建游戏对象,手动定位这些对象,然后编写一个处理对象功能的脚本,而只需几行代码即可立即执行所有操作。该代码将生成通过单个函数调用进行绘制和处理的 GUI 控件。

二、基础知识

1.使用 IMGUI 创建控件

Unity 的 IMGUI 控件使用一个名为 OnGUI() 的特殊函数。只要启用包含脚本,就会在每帧调用 OnGUI() 函数,就像 Update() 函数一样。

IMGUI 控件本身结构非常简单。此结构如以下示例中所示。
代码如下(示例):

/* 示例关卡加载程序 */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {
            
    void OnGUI ()
    {
        // 创建背景框
        GUI.Box(new Rect(10,10,100,90), "Loader Menu");
    
        // 创建第一个按钮。如果按下此按钮,则会打印场景1 
        // 创建第一个按钮。如果按下此按钮,则会打印场景2 
        if (GUI.Button(new Rect(20, 40, 80, 20), "Level 1"))
        {
            Debug.Log("加载关卡1");
        }

        // 创建第二个按钮。
        if (GUI.Button(new Rect(20, 70, 80, 20), "Level 2"))
        {
            Debug.Log("加载关卡2");
        }
    }
}

效果:
在这里插入图片描述

让我们仔细研究一下示例代码:

第一个 GUI 行 GUI.Box (Rect (10,10,100,90), “Loader Menu”); 将显示一个标题文本为 “Loader Menu” 的 Box 控件。该语句遵循典型的 GUI 控件声明模式(我们接下来马上探讨此主题)。

下一个 GUI 行是 Button 控件声明。请注意,该声明与 Box 控件声明略有不同。具体而言,整个 Button 声明都位于 if 语句内。当游戏运行并单击 Button 时,此 if 语句返回 true,并执行 if 代码块中的所有代码。

由于每帧都会调用 OnGUI() 代码,因此无需显式创建和销毁 GUI 控件。声明控件的行与创建控件的行是同一行。如果需要在特定时间显示控件,可以使用任何类型的脚本逻辑来执行此操作。

代码如下(示例):

/* 闪烁按钮示例 */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour
{
            
    void OnGUI () 
    {
        if (Time.time % 2 < 1) 
        {
            if (GUI.Button (new Rect (10,10,200,20), "Meet the flashing button"))
            {
                print ("You clicked me!");
            }
        }
    }
}

此处,每隔一秒才调用一次 GUI.Button(),因此按钮会出现再消失。当然,用户只能在按钮可见时单击按钮。

如您所见,可使用任何所需的逻辑来控制 GUI 控件的显示和运行时间。

2.控件剖析

声明 GUI 控件时,需要三段关键信息:

Type (Position, Content)

可以看到,此结构是一个带有两个参数的函数。我们现在将探讨此结构的细节。

Type
Type 是指 Control Type(控件类型)__;通过调用 Unity 的 GUI 类或 GUILayout 类中的函数来声明该类型(在本指南的布局模式部分对此进行了详细讨论)。例如,__GUI.Label() 将创建非交互式标签。本指南稍后的控件部分将介绍所有不同的控件类型。

Position
Position 是所有 GUI 控件函数中的第一个参数。此参数本身随附一个 Rect() 函数。Rect() 定义四个属性:最左侧位置、最顶部位置、总宽度、总高度。所有这些值都以整数提供,对应于像素值。所有 UnityGUI 控件均在屏幕空间 (Screen Space) 中工作,此空间表示已发布的播放器的分辨率(以像素为单位)。

坐标系基于左上角。Rect(10, 20, 300, 100) 定义一个从坐标 10,20 开始到坐标 310,120 结束的矩形。值得再次强调的是,Rect()中的第二对值是总宽度和高度,而不是控件结束的坐标。这就是为什么上面提到的例子结束于 310,120 而不是 300,100。

可使用 Screen.width 和 Screen.height 属性来获取播放器中可用的屏幕空间的总尺寸。以下示例可能有助于解释如何完成此操作:

代码如下(示例):

/* Screen.width 和 Screen.height 示例 */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
            
    void OnGUI()
    {
        GUI.Box (new Rect (0,0,100,50), "Top-left");
        GUI.Box (new Rect (Screen.width - 100,0,100,50), "Top-right");
        GUI.Box (new Rect (0,Screen.height - 50,100,50), "Bottom-left");
        GUI.Box (new Rect (Screen.width - 100,Screen.height - 50,100,50), "Bottom-right");
    }

}

效果:
在这里插入图片描述

Content

GUI 控件的第二个参数是要与控件一起显示的实际内容。通常会希望在控件上显示一些文本或图像。要显示文本,请将字符串作为 Content 参数传递,如下所示:

代码如下(示例):

/* 按钮内容示例 */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour
{
    public Texture2D icon;
    
    void OnGUI () 
    {
        if (GUI.Button (new Rect (10,10, 100, 50), icon)) 
        {
            print ("you clicked the icon");
        }
    
        if (GUI.Button (new Rect (10,70, 100, 20), "This is text")) 
        {
            print ("you clicked the text button");
        }
    }
}

效果:
在这里插入图片描述

此外还可通过第三个选项在 GUI 控件中一起显示图像和文本。为此,可提供 GUIContent 对象作为 Content 参数,并定义要在 GUIContent 中显示的字符串和图像。

/* 使用 GUIContent 来显示图像和字符串 */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour
{
    public Texture2D icon;

    void OnGUI () 
    {
        GUI.Box (new Rect (10,10,100,50), new GUIContent("This is text", icon));
    }
}

此外,也可以使用 GUIContent 来显示字符串、图标和工具提示。

/* 使用 GUIContent 来显示图像、字符串和工具提示 */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
    public Texture2D icon;
    
    void OnGUI () 
    {
        GUI.Button (new Rect (10,10,100,20), new GUIContent ("Click me", icon, "This is the tooltip"));
        GUI.Label (new Rect (10,40,100,20), GUI.tooltip);
    }
}

GUIContent 构造函数的脚本参考


本文来自: https://docs.unity3d.com/cn/2020.2/Manual/gui-Basics.html.

总结

为了学习Unity编辑扩展,先需要学习一下unity原生的ui系统才能熟练的搭建自己的工具。在网上找了好久,资料很多,但是有点乱,所以之前去官网学习了。在这里我整理了一下官网上的知识,记录并学习下。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UnityGUIUnity游戏引擎中的一个GUI系统,它是一种基于对象的图形用户界面系统,用于在游戏中创建交互式的用户界面。它允许开发者创建按钮、文本框、滑块等交互元素,并通过事件和回调函数来处理用户的输入和交互。 UnityGUI的源码提供了UnityGUI系统的实现细节,可以用于了解和学习UnityGUI的工作原理。通过阅读源码,开发者可以理解UnityGUI是如何创建、渲染和处理UI元素的,以及它是如何与游戏场景和其他组件进行交互的。 在UnityGUI的源码中,可以找到一些核心的类和函数,比如GUI类、GUILayout类和GUIStyle类等。GUI类提供了一系列静态函数来创建和绘制UI元素,比如按钮、标签和文本框。GUILayout类则提供了一组函数来实现自动布局,以便更方便地创建复杂的UI布局。GUIStyle类则包含了一些样式信息,比如字体、颜色和边框等。 通过查看源码,可以了解到UnityGUI的绘制原理和性能优化技巧。比如,可以看到UnityGUI是如何使用批处理技术将多个UI元素合并为一次渲染调用,以减少渲染开销。还可以了解到UnityGUI是如何处理用户的输入事件,并通过回调函数来实现相应的响应。 总之,UnityGUI的源码是一个宝贵的学习资源,可以帮助开发者更好地理解和使用UnityGUI系统。通过深入研究源码,开发者可以从中汲取经验和技巧,提高UI设计和开发的能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值