Version: Unity 6.0 (6000.0)
言語 : 日本語
Migrate custom controls from an earlier version to Unity 6
IMGUI から UI Toolkit への移行

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

このページでは、Unity UI (uGUI) の経験を持つ開発者が、新しい UI Toolkit システムへ移行するためのガイドを提供します。ここでは、uGUI と UI Toolkit の類似点と相違点について説明します。

uGUI はランタイム専用の UI システムであるため、このページではランタイム UI を中心に説明します。UI Toolkit はランタイム UI とエディター UI の両方を作成できます。このガイドは、UI Toolkit の両方のユースケースに適用されます。

UI 階層

uGUI と UI Toolkit はどちらも、UI を階層ツリー構造内でビルドおよび維持します。uGUI では、この階層のすべての要素は、階層ビューパネルで個々のゲームオブジェクトとして表示されます。UI Toolkit では、ビジュアル要素は ビジュアルツリー に編成されます。ビジュアルツリー はパネルに表示されません。

UI Toolkit の UI 階層を表示およびデバッグするには、UI デバッガーを使用します。UI デバッガーは、エディターツールバーの Window > UI Toolkit > Debugger にあります。

UI デバッガー
UI デバッガー

主な相違点

Canvas と UIDocument

uGUI の Canvas コンポーネントは、UI Toolkit の UIDocument コンポーネントに似ています。どちらもゲームオブジェクトにアタッチされる MonoBehaviour です。

uGUI では、Canvas コンポーネントは UI ツリーのルートに位置します。Canvas Scaler コンポーネントと連携して、下にある UI のソート順、レンダリング、スケーリングモードを決定します。

UI Toolkit では、UIDocument コンポーネントには PanelSettings オブジェクトへの参照が含まれます。PanelSettings には、スケールモードやソート順など、UI のレンダリング設定が含まれています。複数の UIDocument コンポーネントが同じ PanelSettings オブジェクトを指すことができ、同じシーンで複数の UI 画面を使用する場合のパフォーマンスが最適化されます。

Panel Settings
Panel Settings

uGUI では、UI ツリーの階層は、Canvas コンポーネントを保持するゲームオブジェクトの下に位置します。UI Toolkit では、UIDocument コンポーネントが、ビジュアルツリーのルート要素への参照を保持します。

UIDocument コンポーネントには、UI レイアウトを定義した UXML ファイルへの参照も含まれており、ランタイムにはそこからビジュアルツリーがビルドされます。詳細については、UI の作成 セクションを参照してください。

注意エディター UI の場合、UIDocument コンポーネントは必要ありません。EditorWindow からカスタムクラスを派生させてから、CreateGUI() を実装できます。実際の例については、カスタムエディターウィンドウの作成 に関するガイドを参照してください。

ゲームオブジェクトコンポーネントとビジュアル要素の比較

UI Toolkit では、UI 要素をコントロールまたはビジュアル要素と呼びます。UI 要素の例は以下のとおりです。

  • コントロール
  • ボタン
  • テキストラベル

uGUI は、ゲームオブジェクトから UI 階層をビルドします。新しい UI 要素を追加するには、階層に新しいゲームオブジェクトを追加する必要があります。個々のコントロールは MonoBehaviour コンポーネントとして実装されます。

UI Toolkit では、ビジュアルツリー が仮想化され、ゲームオブジェクトを使用しません。階層ビューで UI 階層をビルドしたり表示したりすることができなくなりますが、各 UI 要素にゲームオブジェクトを使用することによるオーバーヘッドが解消されます。

uGUI では、UI 要素は、UIBehavior 基本クラスから (直接または間接的に) 派生します。同様に、UI Toolkit では、すべての UI 要素は、VisualElement という基本クラスから派生します。重要な違いは、VisualElement クラスは MonoBehaviour から派生しないということです。ビジュアル要素はゲームオブジェクトにアタッチできません。

スクリプトでの UI Toolkit コントロールの操作は、uGUI コントロールの操作とよく似ています。

以下の表は、uGUI の UI コントロールとその UI Toolkit の対応するものとの一般的なスクリプトの相互作用を示しています。

アクション uGUI UI Toolkit
ラベルにテキストを書き込む m_Label.text = "My Text"; m_Label.text = "My Text";
トグルの状態を読み取る bool isToggleChecked = m_Toggle.isOn; bool isToggleChecked = m_Toggle.value;
ボタンへのコールバックの割り当て m_Button.onClick.AddListener(MyCallbackFunc); m_Button.clicked += MyCallbackFunc_1;
または
m_Button.RegisterCallback<ClickEvent>(MyCallbackFunc_2);

コントロールとそのプロパティやイベントについての詳細は、コントロールの概要 ページを参照してください。

UI 要素へのアクセス

uGUI では、スクリプトが UI 要素にアクセスする方法は 2 つあります。

  • エディターで UI コンポーネントへの参照を割り当てる。
  • GetComponentInChildren<T>() などのヘルパー関数を使用して階層内のコンポーネントを検索する。

UI Toolkit にはゲームオブジェクトやコンポーネントが存在しないため、エディターでコントロールへの参照を直接割り当てることはできません。これらの参照は、ランタイムにクエリ関数を使用して解決する必要があります。代わりに、UIDocument コンポーネントからビジュアルツリーにアクセスします。

UIDocumentMonoBehaviour なので、参照として割り当て、プレハブの一部にすることができます。UIDocument コンポーネントは、ルートビジュアル要素への参照を保持します。ルートからスクリプトは、uGUI と同様に、タイプ別または名前別に子要素を見つけることができます。

以下の表は、Unity UI と UI Toolkit での UI コントロールのアクセス方法を直接比較したものです。

アクション uGUI UI Toolkit
UI要素を名前で探す transform.FindChild("childName"); rootVisualElement.Query("childName");
UI要素のタイプ別検索 transform.GetComponentInChildren<Button>(); rootVisualElement.Query<Button>();
エディターでの参照の直接割り当て 可能 不可

UI の作成

uGUI と UI Toolkit の最大の違いの 1 つは、ユーザーインターフェースの作成です。

uGUI と UI Toolkit の両方で、UI を視覚的にビルドし、エディターでプレビューすることができます。uGUI では、UI がプレハブ内に保存され、個々の UI コントロールにアタッチされたロジックスクリプトも一緒に保存されます。

UI Toolkit では、UI レイアウトは UI Builder で作成され、1 つまたは複数の UXML ファイルとして保存されます。ランタイムに、ビジュアルツリーがメモリ内でアセンブルする UXML ファイルを UIDocument コンポーネントがロードします。

uGUI と同様の方法では、スクリプトから直接 UI コントロールを作成し、ランタイムにビジュアルツリーに追加することができます。

プレハブ( Prefabs )

uGUI は、ビジュアルとロジックの両方を含む個々の UI コントロールとプレハブにゲームオブジェクトを使用します。UI Toolkit は、ロジックとレイアウトを分離するため、再利用性に対して異なるアプローチを採用しています。再利用可能な UI コンポーネントは、UXML とカスタムコントロールを使用して作成できます。

UI Toolkit でプレハブと同様のテンプレートを作成するには、以下の手順に従います。

  1. 部分的な UI 要素のための UXML ファイルを作成します。
  2. UIDocument コンポーネントでゲームオブジェクトを作成します。
  3. ゲームオブジェクト内の UXML ファイルを参照します。
  4. UI コンポーネントのロジックをハンドルするスクリプトを同じゲームオブジェクトに追加します。
  5. ゲームオブジェクトをプレハブとして保存します。

UI レイアウト

uGUI で個々の UI 要素を画面上に配置するのは、手動で行う必要があります。デフォルトでは、UI コントロールはフリーフローティングで、直接の親からのみ影響を受けます。同じ親の下にある他の UI コントロールは、兄弟の位置やサイズに影響を与えません。ピボットやアンカーは、要素の位置やサイズを制御します。

UI Toolkit のレイアウトシステムは、ウェブデザインの影響を受けており、自動レイアウト生成に基づいています。自動レイアウトシステムはデフォルトですべての要素に影響を与え、要素のサイズや位置は同じ親の下にある他の要素に影響を与えます。

UI Toolkit のデフォルトの動作は、uGUI の VerticalLayoutGroup の中にすべての要素を配置し、それぞれに LayoutElement コンポーネントを追加するのと同じです。

自動レイアウト生成を無効にするには、ビジュアル要素の IStyle position プロパティを変更します。すべてのビジュアル要素はこのプロパティを持っています。コードサンプルについては、ビジュアルツリー を参照してください。

UI Toolkit には、UI 要素のアンカーやピボットに関する直接的に同等なものはありません。これは、uGUI と比べて基本的なレイアウトが異なるためです。

要素のサイズと位置は、レイアウトエンジンによって制御されます。詳細については、レイアウトエンジン座標と位置システム を参照してください。

レンダリングの順番

uGUI では、階層内のゲームオブジェクトの順番によって、レンダリングの順番が決まります。階層の下にあるオブジェクトは最後にレンダリングされ、一番上に表示されます。複数のキャンバスがあるシーンでは、ルートの Canvas コンポーネントの Sort Order が、個々の UI ツリーのレンダリング順を決定します。

UI Toolkit の ビジュアルツリー 内のレンダリング順は、同じように動作します。親要素は子の前にレンダリングされ、子は最初から最後の順にレンダリングされます。そのため、最後が一番上に表示されます。複数の UI Document があるシーンでは、レンダリング順はルートの UIDocument コンポーネントの Sort Order 設定によって決まります。

uGUI で要素のレンダリング順を変更する (例えば、ある要素を上に表示する) には、ゲームオブジェクトの Transform コンポーネントの sibling 関数を呼び出します。VisualElement クラスは、レンダリング順を制御する同等の関数を提供します。すべての UI Toolkit コントロールはこのクラスから派生しているため、すべてのコントロールがこの関数にアクセスできます。

以下の表は、レンダリング順を制御する uGUI 関数と、それに相当する UI Toolkit 関数を示しています。

アクション uGUI UI Toolkit
要素を他の兄弟の下にレンダリングする transform.SetAsFirstSibling(); myVisualElement.SendToBack();
要素を他の兄弟の上にレンダリングする transform.SetAsLastSibling(); myVisualElement.BringToFront();
要素の兄弟に対するレンダリング順序を手動で制御する transform.SetSiblingIndex(newIndex); myVisualElement.PlaceBehind(sibling);
myVisualElement.PlaceInFront(sibling);

イベント

uGUI と同様に、UI Toolkit のユーザーインタラクションはイベントをトリガーします。コードは、ボタンの押下やスライダーの移動などのイベントでコールバックを受信するようにサブスクライブできます。

uGUI では、すべての UI 要素が MonoBehaviour に基づいており、エディターでイベントを公開することができます。これにより、他の UI 要素の非表示や表示、コールバック関数の割り当てなど、他のゲームオブジェクトとのロジックを設定することができます。

uGUI ボタンの OnClick Inspector
uGUI ボタンの OnClick Inspector

UI Toolkit では、ロジックと UI レイアウトが別々に保存されます。コールバックをゲームオブジェクトに直接設定したり、プレハブに保存することはできなくなります。ランタイムにすべてのコールバックを設定し、スクリプトで処理する必要があります。

Button playButton = new Button("Play");
playButton.RegisterCallback<ClickEvent>(OnPlayButtonPressed);
...
private void OnPlayButtonPressed(ClickEvent evt)
{
  // Handle button press
}

UI Toolkit のイベントディスパッチシステムは、uGUI のイベントとは異なります。イベントタイプに応じて、イベントはターゲット UI コントロールだけでなく、すべての親コントロールにも送信されます。

詳細については、ディスパッチイベント を参照してください。

同じプロジェクトで uGUI と UI Toolkit を使用

同じプロジェクトで uGUI と UI Toolkit を使用することも可能です。

現在のバージョンでは、UI Toolkit は 3D ワールド空間の選択とレンダリングをサポートしていません。UI Toolkit でゲームメニュー全体を作成し、uGUI で 3D ワールド空間 を作成する必要があります。

また、uGUI でプロジェクト全体を作成し、UI Toolkit で一部のメニュー項目のみを作成することもできます。

それ自体の境界外で相互作用しない項目には、UI Toolkit または uGUI を使用できます。例えば、ランタイム UI では、uGUI を使用してモバイル用のジョイスティックなどの画面上のボタンを作成し、UI Toolkit を使用してモーダルウィンドウを作成できます。

ただし、混合 UI 間の高度なインタラクションは機能しません。

  • キーボードのみを使用して、UI Toolkit のフォーカスされた要素と uGUI の選択されたオブジェクトの間を自由に移動することはできません。移動するには、C# スクリプトを使用して境界要素のイベントを登録し、他のドメインから次の要素を手動で選択またはフォーカスする必要があります。
  • UI Toolkit 階層内に uGUI を埋め込んだり、uGUI 階層内に UI Toolkit を埋め込んだりすることはできません。RenderTexture を使用して描画することはできますが、イベントは対応できません。
  • UI Toolkit のスタイルとイベント規則は uGUI とは異なります。uGUI と UI Toolkit を分散して使用すると、UI に統一感があるプロジェクトを作成するのが難しくなります。

追加リソース

Migrate custom controls from an earlier version to Unity 6
IMGUI から UI Toolkit への移行