自作GUIまとめ(Editor拡張)

自作GUIまとめ(Editor拡張)

 作成したGUIコントロールを一つのクラスへまとめたScriptです。詳しくはFloatFieldの作成 その2(Editor拡張)ラジオボタンの作成(Editor拡張)Sliderの作成(Editor拡張)FloatFieldの作成(Editor拡張)で説明しています。

Script

 作成したGUIコントロールは以下の通りです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEditor;
using UnityEngine.UI;

public enum ControlPosition
{
    Left,
    Center,
    Right
}

public class CustomEditorGUI
{
    public static Color ColorField(string label, Color col, GUIStyle style_label)
    {
        Rect rect = GUILayoutUtility.GetRect(GUIContent.none, style_label);
        col = CustomEditorGUI.ColorField(rect, label, col, style_label);

        return col;
    }

    public static Color ColorField(Rect position, string label, Color col, GUIStyle style_label)
    {
        int color_width = 65;
        int margin = 3;

        Rect rect_label = new Rect(position) { width = position.width - color_width - margin };
        Rect rect_color = new Rect(position) { x = position.x + position.width - color_width, width = color_width };

        EditorGUI.PrefixLabel(rect_label, new GUIContent(label), style_label);

        col = EditorGUI.ColorField(rect_color, col);

        return col;
    }

    public static float FloatField(string label, float val, GUIStyle style_label, GUIStyle style_float, Event ev)
    {
        int default_width = 65;
        Rect rect = GUILayoutUtility.GetRect(GUIContent.none, style_float);
        val = CustomEditorGUI.FloatField(rect, label, val, default_width, style_label, style_float, ev);

        return val;
    }

    public static float FloatField(string label, float val, GUIStyle style_label, GUIStyle style_float, Event ev, params GUILayoutOption[] options)
    {
        int default_width = 65;
        Rect rect = GUILayoutUtility.GetRect(GUIContent.none, style_float, options);
        val = CustomEditorGUI.FloatField(rect, label, val, default_width, style_label, style_float, ev);

        return val;
    }

    public static float FloatField(string label, float val, int text_area_width, GUIStyle style_label, GUIStyle style_float, Event ev)
    {
        Rect rect = GUILayoutUtility.GetRect(GUIContent.none, style_float);
        val = CustomEditorGUI.FloatField(rect, label, val, text_area_width, style_label, style_float, ev);

        return val;
    }

    public static float FloatField(string label, float val, int text_area_width, GUIStyle style_label, GUIStyle style_float, Event ev, params GUILayoutOption[] options)
    {
        Rect rect = GUILayoutUtility.GetRect(GUIContent.none, style_float, options);
        val = CustomEditorGUI.FloatField(rect, label, val, text_area_width, style_label, style_float, ev);

        return val;
    }

    public static float FloatField(string label, float val, int text_area_width, GUIStyle style_label, GUIStyle style_float, Event ev, ControlPosition controlPosition, params GUILayoutOption[] options)
    {
        EditorGUILayout.BeginHorizontal();
        {
            Rect rect;
            switch (controlPosition)
            {
                case ControlPosition.Right:
                    GUILayout.FlexibleSpace();
                    rect = GUILayoutUtility.GetRect(GUIContent.none, style_float, options);
                    break;

                case ControlPosition.Center:
                    GUILayout.FlexibleSpace();
                    rect = GUILayoutUtility.GetRect(GUIContent.none, style_float, options);
                    GUILayout.FlexibleSpace();
                    break;

                default:
                    rect = GUILayoutUtility.GetRect(GUIContent.none, style_float, options);
                    break;
            }
            val = CustomEditorGUI.FloatField(rect, label, val, text_area_width, style_label, style_float, ev);
        }
        EditorGUILayout.EndHorizontal();

        return val;
    }

    public static float FloatField(Rect rect, string label, float val, int text_area_width, GUIStyle style_label, GUIStyle style_float, Event ev)
    {
        float val_speed = 0.3f;
        int id = GUIUtility.GetControlID(FocusType.Passive);

        Rect rect_control = rect;

        int margin = 3;
        int label_width = (int)(rect_control.width - text_area_width - margin);
        Rect rect_label = new Rect(rect_control) { width = label_width };
        EditorGUI.PrefixLabel(rect_label, new GUIContent(label), style_label);

        Rect rect_float = new Rect(rect_control) { x = rect_control.x + rect_control.width - text_area_width, width = text_area_width };
        val = EditorGUI.FloatField(rect_float, val, style_float);

        Vector2 mouse_pos = ev.mousePosition;
        if (ev.button == 0)
        {
            switch (ev.type)
            {
                case EventType.MouseDown:
                    if (rect_label.Contains(mouse_pos))
                    {
                        GUIUtility.hotControl = id;
                        ev.Use();
                    }
                    break;

                case EventType.MouseDrag:
                    if (GUIUtility.hotControl == id)
                    {
                        float dis = ev.delta.x;
                        val = val * 100.0f + dis * 10.0f * val_speed;
                        val = Mathf.Floor(Mathf.Abs(val)) / 100f * Mathf.Sign(val);
                        HandleUtility.Repaint();
                    }
                    break;

                case EventType.MouseUp:
                    if (GUIUtility.hotControl == id)
                    {
                        GUIUtility.hotControl = 0;
                    }
                    break;
            }
        }

        EditorGUIUtility.AddCursorRect(rect_label, MouseCursor.SlideArrow);

        return val;
    }

    static float SliderBase(string label, object obj, float left_val, float right_val, float power, GUIStyle style_label, GUIStyle style_slider, GUIStyle style_slider_thumb, GUIStyle style_float, Event ev)
    {
        float val;
        if (!(obj is int) && !(obj is float))
        {
            Debug.Log("slider error:Wrong type of obj(using float or int)");
            return 0;
        }

        if(obj is int)
        {
            val = (int)obj;
        }
        else
        {
            val = (float)obj;
        }
        float val_speed = (right_val - left_val) * 0.1f;

        int control_id = GUIUtility.GetControlID(FocusType.Passive);
        float remap_left_val = left_val;
        float remap_right_val = right_val;

        if (power != 1f)
        {
            remap_left_val = Mathf.Pow(Mathf.Abs(left_val), 1f / power) * Mathf.Sign(left_val);
            remap_right_val = Mathf.Pow(Mathf.Abs(right_val), 1f / power) * Mathf.Sign(right_val);
            val = Mathf.Pow(Mathf.Abs(val), 1f / power) * Mathf.Sign(val);
        }

        //gui rect
        Rect rect_control = GUILayoutUtility.GetRect(GUIContent.none, style_float);
        int control_height = (int)rect_control.height;
        int margin_left = (int)rect_control.x;
        int margin = 3;
        int float_field_width = 65;
        int slider_width = (int)((rect_control.width - float_field_width - margin * 2) / 2);
        int label_width = (int)(rect_control.width - slider_width - float_field_width - margin * 2);
        int slider_background_height = 6;
        if (style_slider.normal.background != null) slider_background_height = style_slider.normal.background.height;

        //control rect
        Rect rect_label = new Rect(margin_left, rect_control.y, label_width, control_height);
        Rect rect_slider = new Rect(label_width + margin_left + margin, rect_control.y, slider_width, control_height);
        Rect rect_float = new Rect(label_width + slider_width + margin_left + margin * 2, rect_control.y, float_field_width, control_height);

        //slider_thumb rect
        float remap_val = (val - remap_left_val) / (remap_right_val - remap_left_val);
        int slider_thumb_size = 12;
        if (style_slider_thumb.focused.background != null) slider_thumb_size = style_slider_thumb.focused.background.width;
        RectOffset slider_thumb_space = new RectOffset(0, 2, 1, 1);
        int slider_thumb_half_size = slider_thumb_size / 2;

        int rect_slide_area_width = slider_width - slider_thumb_half_size * 2 + slider_thumb_space.left + slider_thumb_space.right;
        Rect rect_slide_area = new Rect(rect_slider.x + slider_thumb_half_size - slider_thumb_space.left, rect_slider.y, rect_slide_area_width, rect_slider.height);
        float slider_pos = Mathf.Lerp(rect_slide_area.x, rect_slide_area.x + rect_slide_area.width, remap_val) - slider_thumb_half_size;
        int slider_thumb_y_pos = (int)(rect_control.y + (rect_control.height - slider_thumb_size + 2) / 2);
        Rect rect_slider_thumb_draw = new Rect(slider_pos, slider_thumb_y_pos, slider_thumb_size, slider_thumb_size);


        //slider overflow
        style_slider.fixedHeight = control_height;
        int overflow_top = (control_height - slider_background_height) / 2;
        style_slider.overflow.top = -overflow_top;
        style_slider.overflow.bottom = overflow_top + slider_background_height - control_height;

        //slider_thumb_overflow
        style_slider_thumb.overflow.top = 0;
        style_slider_thumb.overflow.bottom = 0;

        //control name
        string label_name = label + control_id.ToString();
        string float_name = label_name + "_float";

        int label_id = GUIUtility.GetControlID(FocusType.Passive);
        int slider_id = GUIUtility.GetControlID(FocusType.Passive);
        int slider_thumb_id = GUIUtility.GetControlID(FocusType.Passive);

        bool focus_label = false;

        Vector2 mouse_pos = ev.mousePosition;
        if (ev.button == 0)
        {
            switch (ev.type)
            {
                case EventType.MouseDown:
                    if (rect_slider.Contains(mouse_pos))
                    {
                        float re_scale = (mouse_pos.x - rect_slide_area.x) / (rect_slide_area.width);
                        val = Mathf.Lerp(remap_left_val, remap_right_val, re_scale);
                        val = val * 1000f;
                        val = Mathf.Floor(Mathf.Abs(val)) / 1000f * Mathf.Sign(val);
                        val = Mathf.Clamp(val, remap_left_val, remap_right_val);
                        GUIUtility.hotControl = slider_thumb_id;
                        GUIUtility.keyboardControl = slider_thumb_id;
                        ev.Use();
                        HandleUtility.Repaint();
                    }
                    else if (rect_label.Contains(mouse_pos))
                    {
                        GUIUtility.hotControl = label_id;
                        GUIUtility.keyboardControl = slider_thumb_id;
                        ev.Use();
                        HandleUtility.Repaint();
                    }
                    break;

                case EventType.MouseDrag:
                    if (GUIUtility.hotControl == slider_thumb_id)
                    {
                        float re_scale = (mouse_pos.x - rect_slide_area.x) / (rect_slide_area.width);
                        val = Mathf.Lerp(remap_left_val, remap_right_val, re_scale);
                        val = val * 1000f;
                        val = Mathf.Floor(Mathf.Abs(val)) / 1000f * Mathf.Sign(val);
                        val = Mathf.Clamp(val, remap_left_val, remap_right_val);
                        HandleUtility.Repaint();
                    }
                    else if (GUIUtility.hotControl == label_id)
                    {
                        float dis = ev.delta.x;
                        float delta = dis * 100f * val_speed;
                        if (obj is int)
                        {
                            if (delta < 1f)
                            {
                                delta = 1;
                            }
                        }
                        val = val * 1000f + delta;
                        val = Mathf.Floor(Mathf.Abs(val)) / 1000f * Mathf.Sign(val);
                        val = Mathf.Clamp(val, remap_left_val, remap_right_val);
                        HandleUtility.Repaint();
                    }
                    break;

                case EventType.MouseUp:
                    if (GUIUtility.hotControl == slider_thumb_id || GUIUtility.hotControl == label_id)
                    {
                        GUIUtility.hotControl = 0;
                    }
                    break;
            }
        }
        EditorGUIUtility.AddCursorRect(rect_label, MouseCursor.SlideArrow);

        if (GUI.GetNameOfFocusedControl() == float_name || GUIUtility.keyboardControl == slider_thumb_id) focus_label = true;
        //slider and label
        if (ev.type == EventType.Repaint)
        {
            style_label.Draw(rect_label, new GUIContent(label), false, false, false, focus_label);
            style_slider.Draw(rect_slider, GUIContent.none, slider_id);
            style_slider_thumb.Draw(rect_slider_thumb_draw, GUIContent.none, slider_thumb_id);
        }

        //float field
        if(power != 1f) val = Mathf.Pow(Mathf.Abs(val), power) * Mathf.Sign(val);
        GUI.SetNextControlName(float_name);
        if(obj is int)
        {
            val = EditorGUI.IntField(rect_float, (int)val, style_float);

        }
        else
        {
            val = EditorGUI.FloatField(rect_float, val, style_float);
        }

        val = Mathf.Clamp(val, Mathf.Min(left_val, right_val), Mathf.Max(left_val, right_val));

        return val;
    }

    public static float Slider(string label, float val, float left_val, float right_val, GUIStyle style_label, GUIStyle style_slider, GUIStyle style_slider_thumb, GUIStyle style_float, Event ev)
    {
        val = SliderBase(label, val, left_val, right_val, 1, style_label, style_slider, style_slider_thumb, style_float, ev);
        return val;
    }

    public static float PowerSlider(string label, float val, float left_val, float right_val, float power, GUIStyle style_label, GUIStyle style_slider, GUIStyle style_slider_thumb, GUIStyle style_float, Event ev)
    {
        val = SliderBase(label, val, left_val, right_val, power, style_label, style_slider, style_slider_thumb, style_float, ev);
        return val;
    }

    public static int IntSlider(string label, int val, int left_val, int right_val, GUIStyle style_label, GUIStyle style_slider, GUIStyle style_slider_thumb, GUIStyle style_float, Event ev)
    {
        val = (int)SliderBase(label, val, left_val, right_val, 1, style_label, style_slider, style_slider_thumb, style_float, ev);
        return val;
    }

    public static int RadioButton(string[] labels, int selected, GUIStyle style_label, GUIStyle style_radio)
    {
        Event event_current = Event.current;
        Vector2 mouse_pos = event_current.mousePosition;
        int length = labels.Length;
        int margin = 3;
        int button_size = style_radio.normal.background.width;

        for (int i = 0; i < length; i++)
        {
            int control_id = GUIUtility.GetControlID(FocusType.Keyboard);
            Rect rect_control = GUILayoutUtility.GetRect(GUIContent.none, style_radio);
            Rect rect_button = new Rect(rect_control) { width = button_size };
            Rect rect_label = new Rect(rect_control) { x = rect_button.width + margin, width = rect_control.width - rect_button.width - margin };

            EditorGUI.PrefixLabel(rect_label, control_id, new GUIContent(labels[i]), style_label);

            //radio button
            bool is_on = false;
            if (event_current.type == EventType.Repaint)
            {
                if (i == selected)
                {
                    is_on = true;
                }
                style_radio.Draw(rect_button, GUIContent.none, control_id, is_on);
            }

            if (event_current.type == EventType.MouseDown)
            {
                if (rect_control.Contains(mouse_pos))
                {
                    selected = i;
                    GUIUtility.keyboardControl = control_id;
                    HandleUtility.Repaint();
                }
            }
        }

        return selected;
    }

    public static bool Toggle(string label, bool value, GUIStyle style_label, GUIStyle style_toggle)
    {
        Event event_current = Event.current;
        Vector2 mouse_pos = event_current.mousePosition;
        int control_id = GUIUtility.GetControlID(FocusType.Keyboard);
        Rect rect_control = GUILayoutUtility.GetRect(GUIContent.none, style_toggle);

        int margin = 3;
        int toggle_width = 65;

        Rect rect_label = new Rect(rect_control) { width = rect_control.width - toggle_width - margin };
        EditorGUI.PrefixLabel(rect_label, control_id, new GUIContent(label), style_label);

        //radio button
        Rect rect_toggle = new Rect(rect_control) { x = rect_control.x + rect_control.width - toggle_width, width = toggle_width };
        if (event_current.type == EventType.Repaint)
        {
            style_toggle.Draw(rect_toggle, GUIContent.none, control_id, value);
        }

        if (event_current.type == EventType.MouseDown)
        {
            if (rect_toggle.Contains(mouse_pos))
            {
                value = !value;
                GUIUtility.keyboardControl = control_id;
                HandleUtility.Repaint();
            }
        }

        return value;
    }

    public static Vector4 Vector4Field(string label, Vector4 val, GUIStyle style_label, GUIStyle style_float, Event ev)
    {
        int margin = 3;
        int font_size = style_label.fontSize + 2;
        int min_width = 330;

        Rect rect_control;
        Rect rect_label;
        Rect rect_float;
        int float_width;
        int text_area_width;

        if (EditorGUIUtility.currentViewWidth < min_width)
        {
            int control_height = (int)style_float.fixedHeight;
            if (style_float.fixedHeight <= 0) control_height = 18;

            int height = (int)(control_height * 2 + style_float.margin.top);
            rect_control = GUILayoutUtility.GetRect(GUIContent.none, style_float, GUILayout.Height(height));

            rect_label = new Rect(rect_control) { height = control_height };

            rect_float = new Rect(rect_control);

            int left_margin = 30;

            float_width = (int)((rect_control.width - left_margin) / 4 - margin);
            text_area_width = float_width - font_size - margin;

            rect_float.x = rect_control.x + rect_control.width - float_width;
            rect_float.y = rect_control.y + control_height + style_float.margin.top;
            rect_float.width = float_width;
            rect_float.height = control_height;
        }
        else
        {
            rect_control = GUILayoutUtility.GetRect(GUIContent.none, style_float);

            rect_label = new Rect(rect_control) { width = rect_control.width * 0.4f };

            rect_float = new Rect(rect_control);
            float_width = (int)((rect_control.width - rect_label.width) / 4 - margin);
            text_area_width = float_width - font_size - margin;
            rect_float.x = rect_control.x + rect_control.width - float_width;
            rect_float.width = float_width;
        }

        CustomEditorGUI.LabelField(rect_label, label, style_label);

        Rect rect_float_w = new Rect(rect_float);
        Rect rect_float_z = new Rect(rect_float) { x = rect_float_w.x - rect_float.width - margin };
        Rect rect_float_y = new Rect(rect_float) { x = rect_float_z.x - rect_float.width - margin };
        Rect rect_float_x = new Rect(rect_float) { x = rect_float_y.x - rect_float.width - margin };

        val.x = CustomEditorGUI.FloatField(rect_float_x, "X", val.x, text_area_width, style_label, style_float, ev);
        val.y = CustomEditorGUI.FloatField(rect_float_y, "Y", val.y, text_area_width, style_label, style_float, ev);
        val.z = CustomEditorGUI.FloatField(rect_float_z, "Z", val.z, text_area_width, style_label, style_float, ev);
        val.w = CustomEditorGUI.FloatField(rect_float_w, "W", val.w, text_area_width, style_label, style_float, ev);

        return val;
    }

    enum TexType
    {
        Texture,
        Cubemap,
        Texture3D,
        Texture2DArray
    }
    static Object TextureFieldBase(string label, Object obj, TexType texType, GUIStyle style_label, GUIStyle style_float, ref Vector2 scale, ref Vector2 offset, Event ev)
    {
        int font_size = 13;
        int margin = 3;
        Vector2 tex_size = new Vector2(64, 65);
        Rect rect_control = GUILayoutUtility.GetRect(GUIContent.none, style_float, GUILayout.Height(tex_size.y));
        Rect rect_label = new Rect(rect_control) { width = rect_control.width - tex_size.x - margin, height = 18 };
        Rect rect_tex = new Rect(rect_control) { x = rect_control.x + rect_control.width - tex_size.x, width = tex_size.x, height = tex_size.y };

        GUIStyle style_prop = new GUIStyle(style_label);
        style_prop.alignment = TextAnchor.MiddleCenter;

        EditorGUI.PrefixLabel(rect_label, new GUIContent(label), style_label);

        switch (texType)
        {
            case TexType.Texture:
                obj = EditorGUI.ObjectField(rect_tex, obj, typeof(Texture), false);
                break;

            case TexType.Cubemap:
                obj = EditorGUI.ObjectField(rect_tex, obj, typeof(Cubemap), false);
                break;

            case TexType.Texture3D:
                obj = EditorGUI.ObjectField(rect_tex, obj, typeof(Texture3D), false);
                break;

            case TexType.Texture2DArray:
                obj = EditorGUI.ObjectField(rect_tex, obj, typeof(Texture2DArray), false);
                break;
        }

        //scale
        int scale_height = 18;
        int scale_label_width = 80;
        int scale_position_y = (int)rect_control.y + 25;

        Rect rect_tiling_label = new Rect(rect_control.x, scale_position_y, scale_label_width, scale_height);
        CustomEditorGUI.LabelField(rect_tiling_label, "Tiling", style_prop);

        int scale_width = (int)((rect_control.width - tex_size.x - scale_label_width - margin * 2) * 0.5f);
        int text_area_width = scale_width - margin - font_size;
        Rect rect_scale_y = new Rect(rect_tex.x - scale_width - margin, scale_position_y, scale_width, scale_height);
        Rect rect_scale_x = new Rect(rect_scale_y.x - scale_width - margin, scale_position_y, scale_width, scale_height);

        scale.x = CustomEditorGUI.FloatField(rect_scale_x, "X", scale.x, text_area_width, style_label, style_float, ev);
        scale.y = CustomEditorGUI.FloatField(rect_scale_y, "Y", scale.y, text_area_width, style_label, style_float, ev);

        //offset
        int offset_height = 18;
        int offset_label_width = 80;
        int offset_position_y = (int)(rect_control.y + tex_size.y - offset_height);

        Rect rect_offset_label = new Rect(rect_control.x, offset_position_y, offset_label_width, offset_height);
        CustomEditorGUI.LabelField(rect_offset_label, "Offset", style_prop);

        int offset_width = (int)((rect_control.width - tex_size.x - offset_label_width - margin * 2) * 0.5f);
        Rect rect_offset_y = new Rect(rect_scale_x.x, offset_position_y, offset_width, offset_height);
        Rect rect_offset_x = new Rect(rect_scale_y.x, offset_position_y, offset_width, offset_height);

        offset.x = CustomEditorGUI.FloatField(rect_offset_x, "X", offset.x, text_area_width, style_label, style_float, ev);
        offset.y = CustomEditorGUI.FloatField(rect_offset_y, "Y", offset.y, text_area_width, style_label, style_float, ev);

        return obj;
    }

    static Object TextureFieldBase(string label, Object obj, TexType texType, GUIStyle style_label)
    {
        int margin = 3;
        Vector2 tex_size = new Vector2(64, 65);
        Rect rect_control = GUILayoutUtility.GetRect(GUIContent.none, style_label, GUILayout.Height(tex_size.y));
        Rect rect_label = new Rect(rect_control) { width = rect_control.width - tex_size.x - margin, height = 18 };
        Rect rect_tex = new Rect(rect_control) { x = rect_control.x + rect_control.width - tex_size.x, width = tex_size.x, height = tex_size.y };

        GUIStyle style_prop = new GUIStyle(style_label);
        style_prop.alignment = TextAnchor.MiddleCenter;

        EditorGUI.PrefixLabel(rect_label, new GUIContent(label), style_label);

        switch (texType)
        {
            case TexType.Texture:
                obj = EditorGUI.ObjectField(rect_tex, obj, typeof(Texture), false);
                break;

            case TexType.Cubemap:
                obj = EditorGUI.ObjectField(rect_tex, obj, typeof(Cubemap), false);
                break;

            case TexType.Texture3D:
                obj = EditorGUI.ObjectField(rect_tex, obj, typeof(Texture3D), false);
                break;

            case TexType.Texture2DArray:
                obj = EditorGUI.ObjectField(rect_tex, obj, typeof(Texture2DArray), false);
                break;
        }

        return obj;
    }

    public static Texture TextureField(string label, Texture tex, GUIStyle style_label, GUIStyle style_float, ref Vector2 scale, ref Vector2 offset, Event ev)
    {
        tex = TextureFieldBase(label, tex, TexType.Texture, style_label, style_float, ref scale, ref offset, ev) as Texture;
        return tex;
    }
    public static Cubemap CubemapField(string label, Cubemap tex, GUIStyle style_label, GUIStyle style_float, ref Vector2 scale, ref Vector2 offset, Event ev)
    {
        tex = TextureFieldBase(label, tex, TexType.Cubemap, style_label, style_float, ref scale, ref offset, ev) as Cubemap;
        return tex;
    }
    public static Texture3D VolumeTextureField(string label, Texture3D tex, GUIStyle style_label, GUIStyle style_float, ref Vector2 scale, ref Vector2 offset, Event ev)
    {
        tex = TextureFieldBase(label, tex, TexType.Texture3D, style_label, style_float, ref scale, ref offset, ev) as Texture3D;
        return tex;
    }
    public static Texture2DArray Texture2DArrayField(string label, Texture2DArray tex, GUIStyle style_label, GUIStyle style_float, ref Vector2 scale, ref Vector2 offset, Event ev)
    {
        tex = TextureFieldBase(label, tex, TexType.Texture2DArray, style_label, style_float, ref scale, ref offset, ev) as Texture2DArray;
        return tex;
    }

    //no scale offset
    public static Texture TextureField(string label, Texture tex, GUIStyle style_label)
    {
        tex = TextureFieldBase(label, tex, TexType.Texture, style_label) as Texture;
        return tex;
    }
    public static Cubemap CubemapField(string label, Cubemap tex, GUIStyle style_label)
    {
        tex = TextureFieldBase(label, tex, TexType.Cubemap, style_label) as Cubemap;
        return tex;
    }

    public static Texture3D VolumeTextureField(string label, Texture3D tex, GUIStyle style_label)
    {
        tex = TextureFieldBase(label, tex, TexType.Texture3D, style_label) as Texture3D;
        return tex;
    }

    public static Texture2DArray Texture2DArrayField(string label, Texture2DArray tex, GUIStyle style_label)
    {
        tex = TextureFieldBase(label, tex, TexType.Texture2DArray, style_label) as Texture2DArray;
        return tex;
    }

    public static void LabelField(Rect position, string label, GUIStyle style_label)
    {
        Event event_current = Event.current;
        Vector2 mouse_pos = event_current.mousePosition;
        int label_id = GUIUtility.GetControlID(FocusType.Keyboard);
        bool focus_label = false;
        if (event_current.button == 0)
        {
            switch (event_current.type)
            {
                case EventType.MouseDown:
                    if (position.Contains(mouse_pos))
                    {
                        GUIUtility.keyboardControl = label_id;
                        focus_label = true;
                        event_current.Use();
                    }
                    break;
            }
        }

        if (GUIUtility.keyboardControl == label_id) focus_label = true;
        if (Event.current.type == EventType.Repaint)
        {
            style_label.Draw(position, new GUIContent(label), false, false, false, focus_label);
        }
    }
}

これらのGUIコントロールを実行するScriptは以下の通りです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;


public class CustomEditorGUITest : EditorWindow
{
    private Color col = Color.white;
    private float[] vals = { 0f, 0f, 0f, 0f, 0f, 0f };

    private float[] slider_val = { 0f, 0f };
    private int int_slider_val = 0;

    private int selected = 0;

    private bool toggle = false;

    private Vector4 vec4 = Vector4.zero;

    private Texture[] tex = { null, null };
    private Cubemap[] tex_cube = { null, null };
    private Texture3D[] tex3d = { null, null };
    private Texture2DArray[] tex_array = { null, null };
    private Vector2[] scale = { new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(1f, 1f) };
    private Vector2[] offset = { Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero };

    [MenuItem("Tools/CustomEditorGUI")]
    public static void OpenWindow()
    {
        EditorWindow ed = EditorWindow.GetWindow(typeof(CustomEditorGUITest), false, "CustomEditorGUI");
        ed.minSize = new Vector2(285, 456);
    }

    private void OnGUI()
    {
        Event event_current = Event.current;

        GUIStyle style_label = new GUIStyle(GUI.skin.label);
        style_label.focused.textColor = Color.blue;

        GUISkin dark_skin = (GUISkin)EditorGUIUtility.Load("DarkSkin.guiskin");
        GUIStyle style_float = new GUIStyle(dark_skin.textField);
        GUIStyle style_slider = new GUIStyle(dark_skin.horizontalSlider);
        GUIStyle style_slider_thumb = new GUIStyle(dark_skin.horizontalSliderThumb);
        GUIStyle style_radio = new GUIStyle(EditorStyles.radioButton);
        GUIStyle style_toggle = new GUIStyle(dark_skin.toggle);

        //color field
        col = CustomEditorGUI.ColorField("color", col, style_label);

        //float field
        vals[0] = CustomEditorGUI.FloatField("float field 1", vals[0], style_label, style_float, event_current);
        vals[1] = CustomEditorGUI.FloatField("float field 2", vals[1], style_label, style_float, event_current, GUILayout.Width(150));
        vals[2] = CustomEditorGUI.FloatField("float field 3", vals[2], 150, style_label, style_float, event_current);
        vals[3] = CustomEditorGUI.FloatField("float field 4", vals[3], 30, style_label, style_float, event_current, GUILayout.Width(230), GUILayout.Height(30));
        vals[4] = CustomEditorGUI.FloatField("float field 5", vals[4], 80, style_label, style_float, event_current, ControlPosition.Center, GUILayout.Width(200));

        Rect rect = GUILayoutUtility.GetRect(GUIContent.none, style_float, GUILayout.Width(120));
        vals[5] = CustomEditorGUI.FloatField(rect, "float field 6", vals[5], 50, style_label, style_float, event_current);

        slider_val[0] = CustomEditorGUI.Slider("slider", slider_val[0], -5f, 5f, style_label, style_slider, style_slider_thumb, style_float, event_current);
        slider_val[1] = CustomEditorGUI.PowerSlider("power slider", slider_val[1], -5f, 5f, 0.5f, style_label, style_slider, style_slider_thumb, style_float, event_current);
        int_slider_val = CustomEditorGUI.IntSlider("int slider", int_slider_val, -100, 500, style_label, style_slider, style_slider_thumb, style_float, event_current);

        string[] label_radio = {"left", "center", "right"};
        selected = CustomEditorGUI.RadioButton(label_radio, selected, style_label, style_radio);

        toggle = CustomEditorGUI.Toggle("toggle", toggle, style_label, style_toggle);

        vec4 = CustomEditorGUI.Vector4Field("vector 4", vec4, style_label, style_float, event_current);

        //texture
        tex[0] = CustomEditorGUI.TextureField("texture", tex[0], style_label, style_float, ref scale[0], ref offset[0], event_current);
        tex_cube[0] = CustomEditorGUI.CubemapField("cube map", tex_cube[0], style_label, style_float, ref scale[1], ref offset[1], event_current);
        tex3d[0] = CustomEditorGUI.VolumeTextureField("volume texture", tex3d[0], style_label, style_float, ref scale[2], ref offset[2], event_current);
        tex_array[0] = CustomEditorGUI.Texture2DArrayField("texture2d array", tex_array[0], style_label, style_float, ref scale[3], ref offset[3], event_current);

        //texture(no scale offset)
        tex[1] = CustomEditorGUI.TextureField("texture", tex[1], style_label);
        tex_cube[1] = CustomEditorGUI.CubemapField("cube map", tex_cube[1], style_label);
        tex3d[1] = CustomEditorGUI.VolumeTextureField("volume texture", tex3d[1], style_label);
        tex_array[1] = CustomEditorGUI.Texture2DArrayField("texture2d array", tex_array[1], style_label);
    }
}

実行結果

 上記Scriptを実行すると以下の結果が得られます。