Version: 2023.1
言語: 日本語
Unity UI (uGUI) から UI Toolkit への移行
Unity UI

IMGUI から UI Toolkit への移行

このガイドは、Immediate Mode GUI (IMGUI) (即時モード GUI) の経験を持つ開発者が、UI Toolkit に移行するためのものです。このガイドでは、エディター UI に焦点を当てていますが、その情報はランタイム UI にも適用することができます。

主な相違点

コード駆動と UI 駆動

IMGUI は、OnGUI 関数を実装する C# スクリプトで OnGUI 関数を呼び出すことによってコード駆動されます。UI Toolkit は、エディター UI を作成するためのより多くのオプションを提供します。UI Toolkit を使用すると、C# スクリプトで動作を定義することができます。ただし、UI 要素やスタイルを定義する場合は、C# の他に、UI Builder で UI コントロールを視覚的に定義したり、XML 風のテキストファイル (UXML と呼ばれる) で直接記述したりすることができます。詳しくは、簡易な UI Toolkit ワークフロー を参照してください。

即時モードと保持モード

IMGUI では、OnGUI() 関数内で UI を再描画する際に、UI ツリーを記述します。OnGUI() 関数は、イベントが UI に入るとき、または UI を再描画するときに呼び出さなければなりません。異なるイベント間の UI ツリーに関連する情報は永続的ではありません。一方、ビジュアルツリー と呼ばれるツリー構造で UI Toolkit を使ってビジュアル要素を作成します。ビジュアルツリー内の情報は永続的に保持されます。

常時変化と状態変化

IMGUI は、フレームごとに少なくとも 1 回実行される OnGUI() 関数に基づいています。UI の外観や動作は、可能な限りすべてのフレームで定義します。OnGUI() のボディは、多くの条件と異なる状態を含む場合があります。

UI Toolkit は、イベント駆動のシステムで動作します。デフォルトの状態での UI の外観を定義し、イベントに対応する UI の動作を定義します。UI Toolkit で行う変更は、UI の状態に永続的な変化をもたらします。

例えば、IMGUI でのボタンの宣言は以下のようになります。

if (GUILayout.Button("Click me!"))
{
    //Code runs here in frames where the user clicks the button.

    //Code makes changes to the UI for frames where the user has just clicked the button.
}
else
{
    //Code specifies what happens in all other frames.
}

上の例は、UI Toolkit では以下のようになります。

UIDocument document = GetComponent<UIDocument>();

//Create button.
Button button = new Button();
button.text = "Click me!";

//Set up event handler.
button.RegisterCallback<ClickEvent>((ClickEvent evt) =>
{
    //Code runs here after button receives ClickEvent.
});

//Add button to UI.
document.rootVisualElement.Add(button);

UI Toolkit を使ってカスタムエディターウィンドウを作成する完全な例については、簡易な UI Toolkit ワークフロー を参照してください。

IMGUI のサポート

IMGUI コードを VisualElement に置くには IMGUIContainer を使用します。OnGUI() 内で行えることは、すべてサポートされています。

複数の IMGUIContainer を使用し、GUILayout と UI Toolkit のレイアウトを混在させて設定することができます。IMGUIContainer の内部に VisualElement インスタンスを追加することはできません。

IMGUIContainer の例
IMGUIContainer の例

IMGUI から UI Toolkit への変換について

IMGUI と UI Toolkit の間で同等の機能を持つものは以下の表のとおりです。

アクション IMGUI UI Toolkit
エディターウィンドウ の作成 EditorWindow.OnGUI() EditorWindow.CreateGUI()
プロパティドローワー またはプロパティ属性の作成 PropertyDrawer.OnGUI() PropertyDrawer.CreatePropertyGUI()
Inspector 用カスタムエディターの作成 Editor.OnInspectorGUI() Editor.CreateInspectorGUI()

IMGUI と UI Toolkit の間で、同等のメソッド、クラス、属性を以下の表に示します。

IMGUI IMGUI 名前空間 UI Toolkit
AddCursorRect() EditorGUIUtility VisualElement.style.cursor、または UI Builder や USS でビジュアル要素のカーソルテクスチャを設定します。より詳細な相互作用性を実現するには、C# のイベントを使用します。
AreaScope GUILayout UI Toolkit では、一般にスコープは必要ありません。BeginArea() を参照してください。
BeginArea() GUILayout エリアそのものを定義するには、ビジュアル要素を作成し、style.position Position.Absolute に設定します。エリアの子を作成するには、その下に子ビジュアル要素を作成します。
BeginBuildTargetSelectionGrouping() EditorGUILayout 同等のものはありません。
BeginChangeCheck() EditorGUI 変更チェック範囲の各要素にコールバックを登録します。カスタム Inspector のシリアル化されたフィールドの代わりとして PropertyField を使用する場合、以下を使用します。PropertyField.RegisterCallback<SerializedPropertyChangeEvent>() またはPropertyField.RegisterValueChangeCallback()。その他のすべて場合には、以下を使用します。VisualElement.RegisterCallback<ChangeEvent<T>>() またはVisualElement.RegisterValueChangedCallback<T>().
BeginDisabledGroup() EditorGUI VisualElement.SetEnabled(false)
BeginFoldoutHeaderGroup() EditorGUI, EditorGUILayout Foldout() を参照してください。
BeginGroup() GUI BeginArea() を参照してください。
BeginHorizontal() EditorGUILayout, GUILayout BeginArea() を参照してください。
BeginProperty() EditorGUI BeginProperty()/EndProperty() を使って、簡易なコントロールをシリアル化されたプロパティにバインドする場合、bindingPath または binding-path UXML 属性を設定すれば、BindProperty() を呼び出すことによって UI Toolkit で行うことができます。BeginProperty()/EndProperty() を使って、複雑なカスタム UI から単一のプロパティを作る場合、それは UI Toolkit でうまくサポートされません。
BeginScrollView() EditorGUILayout, GUI, GUILayout UnityEngine.UIElements.ScrollView
BeginToggleGroup() EditorGUILayout 同等のものはありません。
BeginVertical() EditorGUILayout, GUILayout BeginArea() を参照してください。
BoundsField() EditorGUI, EditorGUILayout BoundsField
BoundsIntField() EditorGUI, EditorGUILayout BoundsIntField
Box() GUI, GUILayout Box
BringWindowToBack() GUI Window() を参照してください。
BringWindowToFront() GUI Window() を参照してください。
Button() GUI, GUILayout Button
CanCacheInspectorGUI() EditorGUI 保持モードでは必要ありません。
ChangeCheckScope EditorGUI UI Toolkit で、一般的にスコープは必要ありません。BeginChangeCheck() を参照してください。
ColorField() EditorGUI, EditorGUILayout ColorField
CommandEvent() EditorGUIUtility 一般に保持モードでは必要ありません。イベント処理には C# のコールバックを使用します。
CurveField() EditorGUI, EditorGUILayout CurveField
DelayedDoubleField() EditorGUI, EditorGUILayout DoubleFieldisDelayed を true に設定します。
DelayedFloatField() EditorGUI, EditorGUILayout FloatFieldisDelayed を true に設定します。
DelayedIntField() EditorGUI, EditorGUILayout IntegerFieldisDelayed を true に設定します。
DelayedTextField() EditorGUI, EditorGUILayout TextFieldisDelayed を true に設定します。
DisabledScope EditorGUI UI Toolkit で、一般的にスコープは必要ありません。BeginDisabledGroup() を参照してください。
DoubleField() EditorGUI, EditorGUILayout DoubleField
DragWindow() GUI Window() を参照してください。
DrawPreviewTexture() EditorGUI 同等のものはありません。
DrawRect() EditorGUI VisualElement を使用します。style.positionAbsolute に設定します。style.topstyle.left を設定して、位置を定義します。style.widthstyle.height を設定して、サイズを定義します。style.backgroundColor を設定して、色を指定します。
DrawTexture() GUI Imagecolor の代わりに tintColor を設定します。false alphaBlend と同等のものはありません。borderWidthborderWidthsborderRadiusborderRadiuses と同等のものはありません。
DrawTextureAlpha() EditorGUI 同等のものはありません。
DrawTextureWithTexCoords() GUI ImagetexCoords の代わりに uv を設定します。false alphaBlend と同等のものはありません。
DropdownButton() EditorGUI, EditorGUILayout 正確に同等なものはありません。DropdownButton() の代わりに、すべて揃ったDropdownField を使用します。
DropShadowLabel() EditorGUI Label。影の値を style.textShadow で設定します。
EditorToolbar() EditorGUILayout 各ツールに 1 つずつ ToolbarButton を持つ Toolbar を作成します。各 ToolbarButton について、クリックされたときのコールバックを登録し、ToolManager.SetActiveTool() または ToolManager.RestorePreviousTool() を呼び出し、それぞれそのボタンでツールをアクティブまたは非アクティブ化します。
EndArea() GUILayout BeginArea() を参照してください。
EndBuildTargetSelectionGrouping() EditorGUILayout BeginBuildTargetSelectionGrouping() を参照してください。
EndChangeCheck() EditorGUI BeginChangeCheck() を参照してください。
EndDisabledGroup() EditorGUI BeginDisabledGroup() を参照してください。
EndFoldoutHeaderGroup() EditorGUI, EditorGUILayout Foldout() を参照してください。
EndGroup() GUI BeginArea() を参照してください。
EndHorizontal() EditorGUILayout, GUILayout BeginArea() を参照してください。
EndProperty() EditorGUI BeginProperty() を参照してください。
EndScrollView() EditorGUILayout, GUI, GUILayout BeginScrollView() を参照してください。
EndToggleGroup() EditorGUILayout BeginToggleGroup() を参照してください。
EndVertical() EditorGUILayout, GUILayout BeginArea() を参照してください。
EnumFlagsField() EditorGUI, EditorGUILayout EnumFlagsField
EnumPopup() EditorGUI, EditorGUILayout EnumField
ExpandHeight() GUILayout 同等のものはありません。
ExpandWidth() GUILayout 同等のものはありません。
FlexibleSpace() GUILayout Space() を参照してください。
FloatField() EditorGUI, EditorGUILayout FloatField
FocusControl() GUI VisualElement.Focus()
FocusTextInControl() EditorGUI TextField.Focus()
FocusWindow() GUI Window() を参照してください。
Foldout() EditorGUI, EditorGUILayout Foldout
GetControlRect() EditorGUILayout EditorGUILayout から EditorGUI への変換にのみ必要です。UI Toolkit では必要ありません。
GetNameOfFocusedControl() GUI VisualElement.focusController.focusedElement
GetPropertyHeight() EditorGUI PropertyField.layout.height
GradientField() EditorGUI, EditorGUILayout GradientField
GroupScope GUI UI Toolkit では、一般にスコープは必要ありません。BeginArea() を参照してください。
Height() GUILayout VisualElement.style.height
HelpBox() EditorGUI, EditorGUILayout HelpBox
HorizontalScope EditorGUILayout, GUILayout UI Toolkit では、一般にスコープは必要ありません。BeginArea() を参照してください。
HorizontalScrollbar() GUI, GUILayout ScrollerdirectionHorizontal に設定します。
HorizontalSlider() GUI, GUILayout SliderdirectionHorizontal に設定します。
インスペクタタイトルバー() EditorGUI, EditorGUILayout 同等のものはありません。
IntField() EditorGUI, EditorGUILayout IntegerField
IntPopup() EditorGUI, EditorGUILayout 同等のものはありません。
IntSlider() EditorGUI, EditorGUILayout SliderInt
Label() GUI, GUILayout Label
LabelField() EditorGUI, EditorGUILayout TextFieldisReadOnly を true に設定します。
LayerField() EditorGUI, EditorGUILayout LayerField
LinkButton() EditorGUI, EditorGUILayout 同等のものはありません。
Load() EditorGUIUtility C# を使用している場合は、この関数をそのまま使用し、その戻り値を VisualElement.style のプロパティに代入することができます。USS の場合は、関数 resource() に、Load() に使用するものと同じ引数を使います。
LongField() EditorGUI, EditorGUILayout LongField
MaskField() EditorGUI, EditorGUILayout MaskField
MaxHeight() GUILayout VisualElement.style.maxHeight
MaxWidth() GUILayout VisualElement.style.maxWidth
MinHeight() GUILayout VisualElement.style.minHeight
MinMaxSlider() EditorGUI, EditorGUILayout MinMaxSlider
MinWidth() GUILayout VisualElement.style.minWidth
ModalWindow() GUI Window() を参照してください。
[NonReorderable] 属性 ListView.reorderable が false であることを確認してください。
ObjectField() EditorGUI, EditorGUILayout ObjectField
PasswordField() EditorGUI, EditorGUILayout, GUI, GUILayout TextFieldisPasswordField を true に設定します。
PixelsToPoints() EditorGUIUtility UI Toolkit での使用に有効です。
PointsToPixels() EditorGUIUtility UI Toolkit での使用に有効です。
Popup() EditorGUI, EditorGUILayout PopupField<T0>
ProgressBar() EditorGUI ProgressBar
PropertyField() EditorGUI, EditorGUILayout PropertyField
PropertyScope EditorGUI UI Toolkit で、一般的にスコープは必要ありません。BeginProperty() を参照してください。
RectField() EditorGUI, EditorGUILayout RectField
RectIntField() EditorGUI, EditorGUILayout RectIntField
RepeatButton() GUI, GUILayout RepeatButton
ScrollTo() GUI ScrollView.ScrollTo() または ScrollView.scrollOffset
ScrollViewScope EditorGUILayout, GUI, GUILayout UI Toolkit で、一般的にスコープは必要ありません。BeginScrollView() を参照してください。
SelectableLabel() EditorGUI, EditorGUILayout LabelisSelectablefocusable を true に設定します。
SelectionGrid() GUI, GUILayout RadioButton
SetNextControlName() GUI VisualElement.name
singleLineHeight EditorGUIUtility USS 変数 --unity-metrics-single_line-height を使用します。
Slider() EditorGUI, EditorGUILayout Slider
Space() EditorGUILayout, GUILayout flex プロパティを使用して、ビジュアル要素間の間隔を設定します。
TagField() EditorGUI, EditorGUILayout TagField
TextArea() EditorGUI, EditorGUILayout, GUI, GUILayout TextFieldmultiline を true に設定し、style.whiteSpaceNormal に設定し、ScrollView.verticalScrollerVisibilityAuto に設定します。
TextField() EditorGUI, EditorGUILayout, GUI, GUILayout TextFieldmultiline を true に設定し、style.whiteSpaceNoWrap に設定します。
Toggle() EditorGUI, EditorGUILayout, GUI, GUILayout Toggle
ToggleGroupScope EditorGUILayout UI Toolkit で、一般的にスコープは必要ありません。BeginToggleGroup() を参照してください。
ToggleLeft() EditorGUI, EditorGUILayout Toggle。ただし、label を設定する代わりに、text を設定します。
Toolbar() GUI, GUILayout 同等のものはありません。
UnfocusWindow() GUI Window() を参照してください。
Vector2Field() EditorGUI, EditorGUILayout Vector2Field
Vector2IntField() EditorGUI, EditorGUILayout Vector2IntField
Vector3Field() EditorGUI, EditorGUILayout Vector3Field
Vector3IntField() EditorGUI, EditorGUILayout Vector3IntField
Vector4Field() EditorGUI, EditorGUILayout Vector4Field
VerticalScope EditorGUILayout, GUILayout UI Toolkit では、一般にスコープは必要ありません。BeginArea() を参照してください。
VerticalScrollbar() GUI, GUILayout ScrollerdirectionVertical に設定します。
VerticalSlider() GUI, GUILayout SliderdirectionVertical に設定します。
Width() GUILayout VisualElement.style.width
Window() GUI, GUILayout 同等のものはありません。

その他の参考資料

Unity UI (uGUI) から UI Toolkit への移行
Unity UI