Unity IMGUI Controls(Automatic layout)使用参考

前言:
Unity原生实现的GUI系统在调试中还是比较方便的,所以这里从官方文档里提取出一些常用的操作,方便自己日后使用的时候快速的查看。
这里介绍的是fixed layout,固定布局,稍后会记录Automatic Layout

IMGUI的介绍,请参见”Unity IMGUI Controls(fixed layout)使用参考"这一篇

至于是使用Fixed Layout和Automatic Layout完全根据使用情况,如果说你的布局
已经确定了,使用fixed Layout就可以了,如果你不确定你的布局是什么,或者不确定
某些控件的数量,使用Automatic Layout就会更加的合理和便利

Automatic Layout和Fixed Layout的区别:

1.Automatic Layout使用时,将GUI替换为GUILayout即可
2.Automatic Layout没有Rect,你不需要指定大小和位置,自动来进行计算和定位

void OnGUI () {
        // Fixed Layout
        GUI.Button (new Rect (25,25,100,30), "I am a Fixed Layout Button");
    
        // Automatic Layout
        GUILayout.Button ("I am an Automatic Layout Button");
    }
image.png

Groups:
允许你在屏幕上定义一个区域,区域内可以包含多个Controls组件,这些组件在
GUI.BeginGroup() and GUI.EndGroup() functions中间,他们被定位在Group的区域内,原点在group的左上角。所以你在移动group的时候,所有的组件都会跟着移动。

void OnGUI () {
        // Fixed Layout
        // Make a group on the center of the screen
        GUI.BeginGroup (new Rect (Screen.width / 2 - 50, Screen.height / 2 - 50, 100, 100));
        // All rectangles are now adjusted to the group. (0,0) is the topleft corner of the group.

        // We'll make a box so you can see where the group is on-screen.
        GUI.Box (new Rect (0,0,100,100), "Group is here");
        GUI.Button (new Rect (10,40,80,30), "Click me");

        // End the group we started above. This is very important to remember!
        GUI.EndGroup ();
    }

Group之间是可以嵌套的,每个都有自己独立的区域。

在Fixed Layout中只有Group,而在Automatic Layout中你可以将多个controls组件放在Areas, Horizontal Groups, and Vertical Groups

 GUILayout.Button ("I am not inside an Area");
        GUILayout.BeginArea (new Rect (Screen.width/2, Screen.height/2, 300, 300));
        GUILayout.Button ("I am completely inside an Area");
        GUILayout.EndArea ();

在Area区域内,控件的宽度会自动进行拉伸为区域的宽度。

使用Automatic Layout对于controls组件的位置排列是从上到下,一个接着一个,
你也可以使用Horizontal and Vertical Groups来进行水平和垂直的布局,并且
他们之间可以相互嵌套,控件的使用更加的灵活。

image.png
private float sliderValue = 1.0f;
    private float maxSliderValue = 10.0f;
    void OnGUI () {
        // Wrap everything in the designated GUI Area
        GUILayout.BeginArea (new Rect (0,0,200,60));

        // Begin the singular Horizontal Group
        GUILayout.BeginHorizontal();

        // Place a Button normally
        if (GUILayout.RepeatButton ("Increase max\nSlider Value"))
        {
            maxSliderValue += 3.0f * Time.deltaTime;
        }

        // Arrange two more Controls vertically beside the Button
        GUILayout.BeginVertical();
        GUILayout.Box("Slider Value: " + Mathf.Round(sliderValue));
        sliderValue = GUILayout.HorizontalSlider (sliderValue, 0.0f, maxSliderValue);

        // End the Groups and Area
        GUILayout.EndVertical();
        GUILayout.EndHorizontal();
        GUILayout.EndArea();
    }

使用GUILayoutOptions来改变重新设置Automatic Layout的默认参数,比如
说按钮的默认宽度是100%填充Area的,我们可以设置他的宽度

void OnGUI () {
        GUILayout.BeginArea (new Rect (100, 50, Screen.width-200, Screen.height-100));
        GUILayout.Button ("I am a regular Automatic Layout Button");
        GUILayout.Button ("My width has been overridden", GUILayout.Width (95));
        GUILayout.EndArea ();
    }

GUILayout中Static Functions:

BeginArea:

public static void BeginArea(Rect screenRect);
public static void BeginArea(Rect screenRect, string text);
public static void BeginArea(Rect screenRect, Texture image);
public static void BeginArea(Rect screenRect, GUIContent content);
public static void BeginArea(Rect screenRect, GUIStyle style);
public static void BeginArea(Rect screenRect, string text, GUIStyle style);
public static void BeginArea(Rect screenRect, Texture image, GUIStyle style);
public static void BeginArea(Rect screenRect, GUIContent content, GUIStyle style);

image.png
 void OnGUI() {
        GUILayout.BeginArea(new Rect(10, 10, 100, 100));
        GUILayout.Button("Click me");
        GUILayout.Button("Or me");
        GUILayout.EndArea();
    }

BeginHorizontal:
水平布局,必须以EndHorizontal结束

image.png

public static void BeginHorizontal(params GUILayoutOption[] options);
public static void BeginHorizontal(GUIStyle style, params GUILayoutOption[] options);
public static void BeginHorizontal(string text, GUIStyle style, params GUILayoutOption[] options);
public static void BeginHorizontal(Texture image, GUIStyle style, params GUILayoutOption[] options);
public static void BeginHorizontal(GUIContent content, GUIStyle style, params GUILayoutOption[] options);

 void OnGUI() {
        GUILayout.BeginHorizontal("box");
        GUILayout.Button("I'm the first button");
        GUILayout.Button("I'm to the right");
        GUILayout.EndHorizontal();
    }

BeginScrollView:

image.png
 public Vector2 scrollPosition;
    public string longString = "This is a long-ish string";
    void OnGUI() {
        scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(100), GUILayout.Height(100));
        GUILayout.Label(longString);
        if (GUILayout.Button("Clear"))
            longString = "";
        
        GUILayout.EndScrollView();
        if (GUILayout.Button("Add More Text"))
            longString += "\nHere is another line";
        
    }

Box&Button:
除了不需要指定Rect之外,没什么其它的区别。可以使用GUILayoutOption来设置宽度

ExpandWidth&ExpandHeight:
允许或禁止横向扩展宽度
允许或禁止纵向扩展高度

image.png
void OnGUI() {
        GUILayout.BeginVertical();
        GUILayout.Button("Short Button", GUILayout.ExpandWidth(false));
        GUILayout.Button("Very very long Button");
        GUILayout.EndVertical();
    }

FlexibleSpace:
插入一个自由灵活的空间,他会占据屏幕中剩余的空间


image.png
public float sliderValue = 1.0F;
    void OnGUI() {
        GUILayout.BeginArea(new Rect(0, 0, 200, 60));
        GUILayout.BeginHorizontal();
        GUILayout.RepeatButton("A button with\ntwo lines");
        GUILayout.FlexibleSpace();
        GUILayout.BeginVertical();
        GUILayout.Box("Value:" + Mathf.Round(sliderValue));
        sliderValue = GUILayout.HorizontalSlider(sliderValue, 0.0F, 10);
        GUILayout.EndVertical();
        GUILayout.EndHorizontal();
        GUILayout.EndArea();
    }

Width&Height:
设置控件的绝对宽度和高度

void OnGUI() {
        GUILayout.Button("A Button with fixed height", GUILayout.Height(300));
    }

HorizontalScrollbar&VerticalScrollbar:
使用上和fixed layout 没有什么区别,不需要指定rect

MaxWidth,MinWith,MaxHeight,MinHeight:
控件最大最小宽,最大最小高度

 private Rect windowRect = new Rect(10, 10, 100, 100);
    private bool scaling = false;
    void OnGUI() {
        windowRect = GUILayout.Window(0, windowRect, ScalingWindow, "resizeable", GUILayout.MinHeight(80), GUILayout.MaxHeight(200));
    }
    void ScalingWindow(int windowID) {
        GUILayout.Box("", GUILayout.Width(20), GUILayout.Height(20));
        if (Event.current.type == EventType.MouseUp)
            scaling = false;
        else
            if (Event.current.type == EventType.MouseDown && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
                scaling = true;
            
        if (scaling)
            windowRect = new Rect(windowRect.x, windowRect.y, windowRect.width + Event.current.delta.x, windowRect.height + Event.current.delta.y);
        
    }

PasswordField,RepeatButton,SelectionGrid,TextArea,TextField,Toggle,Toolbar,VerticalScrollbar,VerticalSlider
Window:
这些使用就不贴代码和解释了,基本上和Fixed Layout使用是一样的,只是个别参数

gui-Extending.html:
这个页面中提到了一些组合控件的经验,比如我们可能会复用某些组件多次,如:
Label+Slider,可以封闭成方法,传递变动的参数,并返回具体结果即可。这通常是在开发较复杂的GUI界面时需要用到,甚至
自己可以为此封装一个GUI工具类,方便自己重用。

// C#
using UnityEngine;
using System.Collections;

public class CompoundControls : MonoBehaviour {     
    
    public static float LabelSlider (Rect screenRect, float sliderValue, float sliderMaxValue, string labelText) {
        GUI.Label (screenRect, labelText);
    
        // <- Push the Slider to the end of the Label
        screenRect.x += screenRect.width; 
    
        sliderValue = GUI.HorizontalSlider (screenRect, sliderValue, 0.0f, sliderMaxValue);
        return sliderValue;
    }

}

// C#
using UnityEngine;
using System.Collections;

public class GUITest : MonoBehaviour {
        
    public Color myColor;
    
    void OnGUI () {
        myColor = RGBSlider (new Rect (10,10,200,30), myColor);
    }
    
    Color RGBSlider (Rect screenRect, Color rgb) {
        rgb.r = CompoundControls.LabelSlider (screenRect, rgb.r, 1.0f, "Red");
    
        // <- Move the next control down a bit to avoid overlapping
        screenRect.y += 20; 
        rgb.g = CompoundControls.LabelSlider (screenRect, rgb.g, 1.0f, "Green");
    
        // <- Move the next control down a bit to avoid overlapping
        screenRect.y += 20; 
    
        rgb.b = CompoundControls.LabelSlider (screenRect, rgb.b, 1.0f, "Blue");
        
        return rgb;
    }   
    
}
image.png

到此为止,如果大家发现有什么不对的地方,欢迎指正,共同提高,感谢您的阅读!

编辑于2018.7.23 天通苑北二区农业银行楼上(^^)

今天的闲言碎语我想说,我最近挺喜欢愤怒的情绪,以前每当想到自己错过的机会难免会伤感遗憾,但从未有多少愤怒,最近发现这样有在说服自我安慰的嫌疑,愤怒应该激怒你去不断尝试探求事实的真相,在你决定这么去做的时候,你应该转换愤怒的情绪为理智冷静,在解决问题的阶段,愤怒会坏事儿,希望自己能够多愤怒带给自己新的问题,并冷静理智的去分析解决他们。
另一点,关于创业,最近听到了几个朋友再次创业的消息,回想起自己当时的创业,我觉得人站在巅峰时,离开选择创业会更有希望,因为在工作中已经证明过自己,他自然会有野心探寻更为广阔的空间和平台,但有些人的创业是迫于些许无奈,犹如在泥泞中创业,只是为爬出淤泥,洗清身上的污垢,与其这样,不如安份打工来得靠谱些,这仅仅是我的个人拙解,创业维艰,生活也是如此,最近C罗的新闻很火,33岁还能保持这么好的身体素质和竞技状态,他背后的负出定是非常人能及的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容