unity 之 IMGUI

9 篇文章 0 订阅

Immediate Mode GUI (IMGUI)

“Immediate Mode” GUI system (also known as IMGUI) 是一个完全独立的功能,以Unity的主要游戏对象为基础的UI. IMGUIIMGUI是一个代码驱动的GUI系统,主要用于作为程序员的工具. 写在OnGUI()方法里面来执行

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

Would result in a button displayed like so:

The result of the above code example

 Immediate Mode GUI通常用来:

  • 创建游戏内调试显示和工具。Creating in-game debugging displays and tools.
  • 为脚本创建一个自定义的属性面板Creating custom inspectors for script components.
  • 创建一个新的编辑器窗口和编辑器工具Creating new editor windows and tools to extend Unity itself.

“Immediate Mode”指IMGUI的创建和绘制方式.写在OnGUI()方法里面,每一帧都执行就像update一样 .

 

IMGUI Basics

Making Controls with IMGUI

Unity’s IMGUI 写在 OnGUI()方法里面. The OnGUI()就像 Update() function方法一样,每帧都执行.

/* Example level loader */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {
            
    void OnGUI ()
    {
        // Make a background box
        GUI.Box(new Rect(10,10,100,90), "Loader Menu");
    
        // Make the first button. If it is pressed, Application.Loadlevel (1) will be executed
        if(GUI.Button(new Rect(20,40,80,20), "Level 1"))
        {
            Application.LoadLevel(1);
        }
    
        // Make the second button.
        if(GUI.Button(new Rect(20,70,80,20), "Level 2")) 
        {
            Application.LoadLevel(2);
        }
    }
}

上面的按钮每一帧都在绘制,当然你也可以不是每帧都调用

/* Flashing button example */
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!");
            }
        }
    }
}

Here, GUI.Button() 这样就是每隔一秒绘制一次

 

Anatomy of a Control

在声明GUI控件时需要三个关键信息:

Type (Position, Content)

注意这个结构是一个有两个参数的函数。现在我们将探讨这个结构的细节。

Type

TypeControl Type, 通过Unity’s GUI class 或者 GUILayout class 定义,比如 GUI.Label() 会创建一个非交互式的标签

Position

 Position 是所有 GUI 控件的第一个参数. 参数本身提供了一个Rect()函数. Rect() 定义了像素的xy,长和宽.所有UnityGUI 都是在屏幕空间上,单位都是像素Screen Space,

可以和 Screen.width and Screen.height 结合使用

/* Screen.width & Screen.height example */
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控件的第二个参数是控件上显示的内容. 通常,您希望在控件上显示一些文本或图像。要显示文本,像这样传递一个字符串作为内容参数:

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
    void OnGUI ()
    {
        GUI.Label (new Rect (0,0,100,50), "This is the text string for a Label Control");
    }
}

要显示图像,声明一个Texture2D变量,并将变量名作为内容参数传递,如下所示

/* Texture2D Content example */
public Texture2D controlTexture;
  ...

void OnGUI () 
{
    GUI.Label (new Rect (0,0,100,50), controlTexture);
}

There is a third option which allows you to display images and text together in a GUI Control. You can provide a GUIContent object as the Content argument, and define the string and image to be displayed within the GUIContent.

/* Using GUIContent to display an image and a string */
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));
    }
}

You can also define a Tooltip in the GUIContent, and display it elsewhere in the GUI when the mouse hovers over it.

/* Using GUIContent to display a tooltip */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
    void OnGUI () 
    {
        // This line feeds "This is the tooltip" into GUI.tooltip
        GUI.Button (new Rect (10,10,100,20), new GUIContent ("Click me", "This is the tooltip"));
        
        // This line reads and displays the contents of GUI.tooltip
        GUI.Label (new Rect (10,40,100,20), GUI.tooltip);
    }
}

你也可以使用GUIContent 显示一个string,  icon, 和一个提示工具(当鼠标滑倒上面时显示的内容) tooltip.

/* Using GUIContent to display an image, a string, and a tooltip */
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 Constructor

public GUIContent();创建一个空的GUIContent


public GUIContent(string text);   构建一个只包含文本的GUIContent

 

 

当使用GUI时,您不需要为简单的文本字符串创建guicontent—这两行代码在功能上是等价的:

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    void OnGUI()
    {
        GUI.Button(new Rect(0, 0, 100, 20), "Click Me");
        GUI.Button(new Rect(0, 30, 100, 20), new GUIContent("Click Me"));
    }
}

public GUIContent(Texture image);  构建一个只包含图像的GUIContent

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    public Texture icon;
    void OnGUI()
    {
        GUI.Button(new Rect(0, 30, 100, 20), new GUIContent(icon));
    }
}

public GUIContent(string text, Texture image);   构建一个包含文本和图像的GUIContent

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    public Texture icon;
    void OnGUI()
    {
        GUI.Button(new Rect(0, 30, 100, 20), new GUIContent("Click me", icon));
    }
}

public GUIContent(string text, string tooltip);

构建一个包含一些文本的GUIContent。当用户将鼠标悬停在全局GUI上时,GUI.tooltip 会显示提示 tooltip.

tooltip需要一个单独的GUI空间来显示,就像下面的GUI.Label(new Rect(0, 40, 100, 40), GUI.tooltip)一样

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    void OnGUI()
    {
        GUI.Button(new Rect(0, 0, 100, 20), new GUIContent("Click me", "This is the tooltip"));

        // If the user hovers the mouse over the button, the global tooltip gets set
        GUI.Label(new Rect(0, 40, 100, 40), GUI.tooltip);
    }
}

public GUIContent(Texture image, string tooltip);  建立一个包含图像的GUIContent。当用户将鼠标悬停在全局GUI上时,

GUI.tooltip 会显示提示 tooltip.   tooltip需要一个单独的GUI空间来显示,就像下面的GUI.Label(new Rect(0, 40, 100, 40), GUI.tooltip)一样


public GUIContent(string text, Texture image, string tooltip);

创建一个既有 text也有 image的GUI控件,鼠标悬停也有提示


public GUIContent(GUIContent src);创建一个GUIContent作为另一个GUIContent的副本。

 

 

 

 

Controls

IMGUI Control Types:控件类型

Label

 Label is non-interactive非交互式。只供显示。无法点击或以其他方式移动。最好只显示信息.

/* GUI.Label example */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{               
    void OnGUI () 
    {
        GUI.Label (new Rect (25, 25, 100, 30), "Label");
    }
}

Button

 Button is a typical interactive 是典型的交互按钮. 当点击时,它会响应一次,不管鼠标停留多长时间。一旦释放鼠标按钮,就会发生响应

在UnityGUI里面, Buttons 点击时返回true ,和if一起使用

/* GUI.Button example */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{                    
    void OnGUI () 
    {
        if (GUI.Button (new Rect (25, 25, 100, 30), "Button")) 
        {
            // This code is executed when the Button is clicked
        }
    }
}

 

RepeatButton

RepeatButton是普通按钮的变体. 不同的是:RepeatButton 将在鼠标按住的时候,一直执行方法

/* GUI.RepeatButton example */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{                  
    void OnGUI () 
    {
        if (GUI.RepeatButton (new Rect (25, 25, 100, 30), "RepeatButton")) 
        {
            // This code is executed every frame that the RepeatButton remains clicked
        }
    }
}

TextField

TextField 是一个交互式的、可编辑的、包含文本字符串的单行字段

TextField将始终显示一个字符串。必须提供要在TextField中显示的字符串。当对字符串进行编辑时,TextField函数将返回编辑后的字符串。要全局声明该字符串,用来更新TextField的内容,如果不采用这种做法,不会更新其内容

/* GUI.TextField example */
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{                    
    private string textFieldString = "text field";
    void OnGUI () 
    {
        textFieldString = GUI.TextField (new Rect (25, 25, 100, 30), textFieldString);
    }
}

 

TextArea

TextArea Control可交互的多行字段

要有一个字符串来接受它的返回值

/* GUI.TextArea example */
using UnityEngine;
using System.Collections;
public class GUITest : MonoBehaviour
{                    
    private string textAreaString = "text area";  
    void OnGUI ()
    {
        textAreaString = GUI.TextArea (new Rect (25, 25, 100, 30), textAreaString);
    }
}

Toggle

Toggle 开关,返回一个bool值,需要变量来就收它,从而实时更新它

 

/* GUI.Toggle example */

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
    private bool toggleBool = true;
    
    void OnGUI () 
    {
        toggleBool = GUI.Toggle (new Rect (25, 25, 100, 30), toggleBool, "Toggle");
    }
}


Toolbar

Toolbar 类似于toggleGroup,是一排button. 一次只能激活工具栏上的一个按钮,并且在单击其他按钮之前,该按钮将一直处于活动状态。此行为模拟典型工具栏的行为。您可以在工具栏上定义任意数量的按钮。

工具栏中的活动按钮通过一个整数进行跟踪. 根据一个string数组决定有几个button,这些button都没有功能,点击没有效果,通过传递一个整数来决定当前活动的是哪个按钮,同时需要一个整数来接收返回的数值,来的值当前活动的按钮

/* GUI.Toolbar example */

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
                    
    private int toolbarInt = 0;
    private string[] toolbarStrings = {"Toolbar1", "Toolbar2", "Toolbar3"};
    
    void OnGUI () 
    {
        toolbarInt = GUI.Toolbar (new Rect (25, 25, 250, 30), toolbarInt, toolbarStrings);
    }

}


 

 

SelectionGrid

 SelectionGrid 是多行的 Toolbar. 您可以确定网格中的列和行数。一次只能激活一个按钮。

它也是通过传递一个整数来决定当前哪个按钮处于活动状态. 您提供的内容数组中的元素数量将决定SelectionGrid中显示的按钮数量。您还可以通过函数参数指定列的数量。

/* GUI.SelectionGrid example */

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
                    
    private int selectionGridInt = 0;
    private string[] selectionStrings = {"Grid 1", "Grid 2", "Grid 3", "Grid 4"};
    
    void OnGUI () 
    {
        selectionGridInt = GUI.SelectionGrid (new Rect (25, 25, 300, 60), selectionGridInt, selectionStrings, 2);
    
    }

}


 

 

HorizontalSlider

HorizontalSlider 控件是一个典型的水平滑动旋钮,可以拖动该旋钮来更改预定的最小值和最大值之间的值。

返回一个float类型的值,用来更新当前滑块所在的位置

/* Horizontal Slider example */

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
                    
    private float hSliderValue = 0.0f;
    
    void OnGUI () 
    {
        hSliderValue = GUI.HorizontalSlider (new Rect (25, 25, 100, 30), hSliderValue, 0.0f, 10.0f);
    }

}


VerticalScrollbar

 VerticalScrollbar 控件类似于滑块控件,但在视觉上类似于web浏览器或文字处理程序的滚动元素。此控件用于导航ScrollView控件。也是返回一个float值

/* Vertical Scrollbar example */

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour
{
                    
    private float vScrollbarValue;
    
    void OnGUI ()
    {
        vScrollbarValue = GUI. VerticalScrollbar (new Rect (25, 25, 100, 30), vScrollbarValue, 1.0f, 10.0f, 0.0f);
    }
}


 

ScrollView

ScrollViews a是显示一组大得多的控件的可视区域的控件。

ScrollViews 需要两个Rects 参数,第一个表示屏幕上可查看的ScrollView区域的位置和大小,就是外围的整体大小, The second Rect 定义了可视区域内包含的空间大小,就是显示区域的大小.如果可查看区域内的空间大于可查看区域,则滚动条将适当显示. 您还必须指定并提供一个2D向量,用于存储显示的可视区域的位置。

/* ScrollView example */

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
                    
    private Vector2 scrollViewVector = Vector2.zero;
    private string innerText = "I am inside the ScrollView";
    
    void OnGUI () 
    {
        // Begin the ScrollView
        scrollViewVector = GUI.BeginScrollView (new Rect (25, 25, 100, 100), scrollViewVector, new Rect (0, 0, 400, 400));
    
        // Put something inside the ScrollView
        innerText = GUI.TextArea (new Rect (0, 0, 400, 400), innerText);
    
        // End the ScrollView
        GUI.EndScrollView();
    }

}


Window

Windows可拖动的控件容器. 他们可以接收和失去focus .因此,它们的实现与其他控件略有不同。每个窗口都有一个id号,当窗口有焦点时,它的内容在一个单独的函数中声明。

Windows是唯一需要附加方法才能正常工作的控件。必须提供要为窗口执行的id号和函数名。在窗口函数中,您可以创建实际的行为或包含的控件,

/* Window example */

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour 
{
                    
    private Rect windowRect = new Rect (20, 20, 120, 50);
    
    void OnGUI ()
    {
        windowRect = GUI.Window (0, windowRect, WindowFunction, "My Window");
    }
    
    void WindowFunction (int windowID) 
    {
        // Draw any Controls inside the window here
    }

}


GUI.changed

检测用户是否在GUI中执行了任何操作(点击一个按钮,拖一个滑块, etc), 从脚本中获取 GUI.changed 的值,如果执行了一个操作,返回true

比如: Toolbar,要根据单击的是工具栏中的哪个按钮来更改特定值的位置. 不需要每时每刻都为每个button声明一个函数,只需要在操作改变时再进行操作,降低功能消耗OnGUI(),

/* GUI.changed example */

using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour
{
                    
    private int selectedToolbar = 0;
    private string[] toolbarStrings = {"One", "Two"};
    
    void OnGUI () 
    {
        // Determine which button is active, whether it was clicked this frame or not
        selectedToolbar = GUI.Toolbar (new Rect (50, 10, Screen.width - 100, 30), selectedToolbar, toolbarStrings);
    
        // If the user clicked a new Toolbar button this frame, we'll process their input
        if (GUI.changed)
        {
            Debug.Log("The toolbar was clicked");
    
            if (0 == selectedToolbar)
            {
                Debug.Log("First button was clicked");
            }
            else
            {
                Debug.Log("Second button was clicked");
            }
        }
    }

}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TO_ZRG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值