Unity を検索

ランタイムで UI Toolkit を使う:その内側を覗く

2022年4月20日 カテゴリ: Engine & platform | 20 分 で読めます
Unity UI toolkit preview
Unity UI toolkit preview
シェア

Is this article helpful for you?

Thank you for your feedback!

UI Toolkit はユーザーインターフェースやエディター拡張を開発するために作られた、機能、リソース、およびツールを集めたものです。UI Toolkit は元々 UI Elements という名前で登場したもので、これは Unity エディター拡張のカスタム UI の開発を容易にする保守モードの UI フレームワークを提供するものです。

UI Toolkit は Unity の最新バージョンで利用可能で、Web 技術から着想を得た親しみやすく直感的なオーサリング体験によって、ランタイム UI の作成をサポートします。この記事では、その機能の特異性を検証し、UGUI に替えてランタイムで UI Toolkit を使い始めるためのヒントをご紹介します。

UI システムの詳細な比較は、こちらのマニュアルをご覧ください。

Unity で使ってみよう

Unity 2021 LTS は現在、ダウンロードして使用することができます。. このリリースは、Unity エディター全体と基礎的な機能を 1 年以上集中して開発し、Unity 2021.1 および Unity 2021.2 TECH ストリームリリースに含まれる機能(さらに 6 か月間の品質向上)と組み合わせたものです。

はじめに、Unity Hub から最新版の Unity をダウンロードします。

Unity Hub login screen

ワークフロー

UI Toolkit を使うことで、UI 制作のワークフローがどのように円滑になるのかを明らかにしましょう。 

アーティストとのコラボレーションによる UI 制作は、複雑な作業となることがあります。アーティストがキャンバスを編集して色やマテリアルの設定をしている間に、開発者はスクリプトやビヘイビア、OnClick リスナーを追加していきます。その後、マージを行う際に、マージのコンフリクトが発生し、早急に解決しなければならない問題が発生することがあります。

UI Toolkit では、アーティストが UXML と USS ファイルを作成し、C# がすべてのロジックを処理することで、このようなマージの衝突を防ぐことができます。たとえば、ボタンの処理は C# のみで行い、ボタン名で問い合わせを行い、UXML や USS ファイルを編集することなくロジックを追加しています。

この処理により、マージが容易になるだけでなく、将来のスタイル変更も容易になります。たとえば、突然プロジェクトのフォントをすべて変更しなければならなくなった場合でも、アセットを 1 つ 1 つ調べてテキスト設定を編集する必要はありません。これにより、見落としの問題につながる面倒な作業を避けることができます。また、ゲームの規模が大きくなればなるほど、この作業はより複雑になります。

UI Toolkit では、パネル設定にすべてのテキスト設定が保持されています。そのため、UI Document のフォントを変更するには、それらの Panel Settings を編集するだけでよいのです。エディタースクリプトでも同様に UGUI をサポートできますが、UI Toolkit のフレームワークはこの処理を自動的に行います。

Visual Element は、ボタン、画像、テキストなど、すべての UI Toolkit 要素のベースクラスです。UI Toolkit におけるゲームオブジェクトのようなものと考えていただければと思います。一方、UI BuilderWindow > UI Toolkit > UI Builder)は、コードを書かずにインターフェイスを作成・編集するためのビジュアルツールです。これは、アーティストやデザイナーにとっても、UI の構築を視覚化しながら行えるため、便利です。

UI Toolkit は、Web 技術にすでに精通している人向けにうってつけのツールで、ロジックとスタイルを分離して整理し、ファイルの衝突を避けることで、アーティストと開発者のコラボレーションを向上させることもできます。UI Builder が要素の位置やスタイル、デザインを担当する一方で、コードはプロジェクト内の別のセクションで処理し、必要な UXML の部分にクエリを出したり、ロジックを接続したりすることができるのです。

UXML をはじめよう

UXML ファイルは、HTML の Web ファイルに相当するものです。ビジュアル要素を表し、UI のヒエラルキーを含んでいます。UXML ドキュメントAssets > Create > UI Toolkit > UI Document で作成できます。その後、UI Builder を使用して、新しく作成した UXML を視覚化して作業します。

ただし、UXML ファイルはゲームオブジェクトとしてではなく、ビジュアル要素のツリーとして扱う必要があることに注意してください。ヒエラルキーを軽くするために、UI Document を 1 つ作成し、すべての UXML 要素をその上に読み込みます。Windows > UI Toolkit > Debugger から UI Toolkit Debugger を呼び出し、UI を視覚化することができます。

 

作業を始めるときの参考として、Windows > UI Toolkit > Samples から、UXML Element のサンプルをご確認ください。

UI Builder のおかげで、ゲームを起動しなくても UXML ファイルの作成、視覚化、テストが可能です。UI コントロール(標準またはユーザーが作成したもの)を UI Builder Library パネルからヒエラルキーにドラッグアンドドロップし、複数の UXML ファイル を組み合わせるだけで、最終的な UI を作成できます。

例えば、3 つの要素で構成される UI があるとします。

  • ライフ
  • スコア
  • 「You win」のポップアップ

「You win」のポップアップには、ライフとスコア、そして Restart ボタンが表示されます。

それぞれの要素は、popup.uxml(health.uxml と score.uxml に Restart ボタンを加えたもの)と個別の UXML ファイルに含まれた形で、ゲームのさまざまな UI パネルで使用されています。そのため、スコアとライフを管理するコードロジック(score.cs と health.cs)はヒエラルキーから独立しています。つまり、UI が画面上に単独で表示されていても、別のポップアップの中に表示されていても、health.cs は常に health.uxml の値を更新することになります。

UXML を組み合わせることで、編集したオブジェクトの可視化を容易にすることもできます。UI Builder ヒエラルキー内の Class List オプションをオンにすると、オブジェクトに影響を与えているものが一目瞭然になり、セレクターを使ってスタイルを整理することができるようになります。

もう 1 つの利点は、Scene ヒエラルキーに関するものです。UI Toolkit では、1 つのキャンバスに何十ものゲームオブジェクトを配置するのではなく、UI Document にリンクした 1 つの UXML ファイルを用意するだけでよいのです。

これに対し、UI Toolkit では下図のようになります。

このワークフローは、特に大規模なチームにとって有利なものです。同じシーンで作業しているとマージ問題が発生する可能性がありますが、各チームメンバーは自分の UXML ファイルを作成し、それをシーン内の 1 つの UI Document に追加することができます。

Panel Settings

Panel Settings アセットAssets > Create > UI Toolkit > Panel Settings Asset)は、ゲーム内で UXML をどのようにインスタンス化、視覚化するかを定義しています。複数の Panel Settings アセットを持つことで、さまざまな UI のスタイルを有効にすることができます。たとえば、あるパネル設定を HUD に採用し、別のパネル設定をミニマップに採用するのは、これらの UI がまったく異なるニーズを持っているため、理にかなっています。

Panel Settings は、UGUI Canvas と Canvas Scaler を合わせたものにテキスト設定などのオプションを追加したものとみなすことができ、パネル内のすべてのテキストが同じベース設定を使用するようにします。もちろん、必要に応じて、個々の UI Document の中でフォントを上書きすることもできます。

イベント

UI Builder はイベント管理のためのものではありませんし、UXML のドキュメントでもありません。ボタンクリックなどのイベントを処理するには、C# スクリプトを作成し、UXML にリンクさせます。

public class UIEventHandler : MonoBehaviour
{
   [SerializeField]
   private UIDocument m_UIDocument;
 
   private Label m_Label;
   private int m_ButtonClickCount = 0;
   private Toggle m_Toggle;
   private Button m_Button;
 
   public void Start()
   {
       var rootElement = m_UIDocument.rootVisualElement;
 
       // This searches for the VisualElement Button named “EventButton”
       // rootElement.Query<> and rootElement.Q<> can both be used
       m_Button = rootElement.Q<Button>("EventButton");
 
       // Elements with no values like Buttons can register callBacks
// with clickable.clicked
       m_Button.clickable.clicked += OnButtonClicked;
 
       // This searches for the VisualElement Toggle named “ColorToggle”
       m_Toggle = rootElement.Query<Toggle>("ColorToggle");
 
       // Elements with changing values: toggle, TextField, etc... 
// implement the INotifyValueChanged interface,
       // meaning they use RegisterValueChangedCallback and 
// UnRegisterValueChangedCallback
       m_Toggle.RegisterValueChangedCallback(OnToggleValueChanged);
 
       // Cache the reference to the Label since we will access it repeatedly.
       // This avoids the relatively costly VisualElement search each time we update
       // the label.
       m_Label = rootElement.Q<Label>("IncrementLabel");
       m_Label.text = m_ButtonClickCount.ToString();
   }
 
   private void OnDestroy()
   {
       m_Button.clickable.clicked -= OnClicked;
       m_Toggle.UnregisterValueChangedCallback(OnToggleValueChanged);
   }
 
   private void OnButtonClicked()
   {
       m_ButtonClickCount++;
       m_Label.text = m_ButtonClickCount.ToString();
   }
 
   private void OnToggleValueChanged(ChangeEvent<bool> evt)
   {
       Debug.Log("New toggle value is: " + evt.newValue);
   }
}

ポジショニング

要素のポジショニングには、デフォルトでFlexbox アーキテクチャを使用します。これにより、ほとんどのレイアウトがコンテナや画面サイズに対応できるようになります。2 つ以上の要素を持つ Visual Element ツリーにこれを適用し、ツリー上で要素がどのように整列するかを定義します。

Absolute ポジショニングで要素を配置することは、その要素が親のポジショニングから相対的に位置決めされ、他のポジショニングに影響したり、逆に影響されたりしないことを意味します。

FlexAlign 設定については、以下の単純なヒエラルキーがその一例となります。

UI Builder インスペクターを使って、以下の設定を編集してください。

  • BasisShrink(親に空白が残っていない場合に指定した比率で縮小する)または Grow(親に空白が残っている場合に指定した比率で拡大する)操作が発生する前の、項目のデフォルトサイズを指します。
  • Direction(行方向と列方向):UGUI の Vertical Layout Group と Horizontal Layout Group にそれぞれ似た動作をさせる場合に使用します。
Table Vertical Layout
  • Wrap:どの要素が入らないかを判断して、入らないと判断された要素を無視し、そうでなければ前の要素の上か下に回します。
Table illustrating wrap
  • Align Items:選択された位置の要素を、その最小サイズを使って詰め込みます。
Item alignment options
  • Justify Content:主軸に沿った要素間の間隔を決定します。
Elements spacing options

Visual Element の位置決めについて詳しくは、UI Toolkit レイアウトエンジンのドキュメンテーションをご覧ください。

スタイリング

UI Toolkit が威力を最大限に発揮するのは、スタイリングにおいてです。スタイルをビジュアル要素に追加するには、USS ファイルAssets > Create > UI Toolkit > StyleSheet)を使用します。これは Unity において、CSS ファイルに相当するもので、CSS と同じルールベースの形式を使用しています。

なお、ユーザー作成の USS ファイルは、UI の動作に必須ではありません。実行時のスタイルとエディターのスタイルはデフォルトで提供されていますが、カスタム USS を作成することで、すでに提供されているものを拡張したり、ゼロからスタイルを作成することができます。

スタイルセレクターUI Builder Inspector StyleSheet パネルから追加し、コードまたは UI Builder を使用して編集することが可能です。

UI Builder の USS スタイルセレクター

インスペクターで追加されたクラスとのマッチング

上のスクリーンショットでは、ボタンに .RedButton セレクターが追加されています。このようにセレクターは、すべてのボタンが自動的に持つ、組み込みの .unity-text-element および .unity-button クラス と並んで表示されます。

以下は、.RedButton クラスを持つすべての要素の背景色を赤に設定する USS ルールの例です。ルールの最初の行はクラス名を使ったセレクターで、その後に適用するスタイルのリストが続きます。

.RedButton { background-color: red; }

CSS と同様に、クラスを組み合わせることで、ルールのセレクターの範囲をさらに限定することができます。

.RedButton.BlueText { color: blue; }

この例では、.RedButton と .BlueText クラスの両方を持つオブジェクトだけが、青いテキストを持つことになります。先ほどのスニペットと組み合わせると、ボタンの背景も赤になります。

CSS スタイルと同様に、USS ファイルを使用して、状態に応じてオブジェクトの外観を上書きすることができます。

.unity-button:hover { background-color: red; }

この例では、ホバー状態にあるすべてのボタンの背景が赤に切り替わります。ホバー状態のスタイル設定をプレビューして効果を確認するには、UI Builder ツールバーにある Preview をクリックします。

詳細な例

UI Toolkit の基本が分かったところで、UGUI と UI Toolkit をそれぞれ使ってインターフェースを作成する場合を比較するための例を作ってみましょう。目標は、以下の 2 つの効果を持つマウスホバーを含む、シンプルなメニューを構築することです。

  • ボタンの背景色の変更
  • ボタンの文字色の変更

このメニューを UGUI で作成するには、ヒエラルキーを以下のように設定します。

また、いくつかのオブジェクトには、追加のコンポーネントを追加する必要があります。

  • Menu は背景に画像を使用し、位置合わせのためのアンカーを必要とします。
  • Buttons は、きちんと位置が合うように正しくアンカーを設定する必要があります。
  • RestartQuit ボタンについては以下の作業が必要です。
    • ホバー時に動的に文字色を変化させるスクリプトの追加。
    • 背景色を変更するためのボタン部品の設定(エディターで編集)。

この例では、Quit は赤いボタンを定義するプレハブになっています。

さて、UI Builder を使ってメニューを作成するには、まず同様のヒエラルキーを作ります。

Popup AlignCenter に、Buttons Flex DirectionRow に設定すると、UI Toolkit ポップアップはこのような表示になります。

QuitButton.uxml という Quit ボタンのプレハブに相当するコンポーネントを使用しているために、Quit ボタンが赤くなっていることに注意してください。

UI Toolkit の魔法が本当に発動しているところを見るには、たくさんのルールが記述された PopupStyle.uss を追加します...

.background {
   background-image: url('/Assets/Assets/OptionsMenu.png#OptionsMenu');
   width: 500px;
   height: 300px;
}
 
.title {
   font-size: 32px;
   color: rgb(255, 255, 255);
}
 
.unity-base-field__input {
   background-color: rgba(0, 0, 0, 0);
   background-image: url('/Assets/Assets/OptionsMenu9Slice.png#OptionsMenu9Slice_2');
   width: 300px;
   height: 75px;
   font-size: 20px;
   color: rgba(255, 255, 255, 0.5);
   -unity-text-align: middle-center;
}
 
.unity-button {
   color: white;
   background-color: rgba(0, 0, 0, 0);
   background-image: url('/Assets/Assets/StartMenu.png#StartMenu_ButtonDefault');
   width: 160px;
   height: 30px;
   -unity-slice-bottom: 1;
}
 
.unity-button:hover {
   color: rgb(0, 21, 255);
}
 
#Restart {
   -unity-background-image-tint-color: rgb(112, 202, 125);
}

ここでは、セレクターの優先順位があることに注意してください。たとえば、UXML に直接記述されたスタイルは、USS ファイルに記述されたものを上書きします。ここでは、要素の幅と高さを PopupStyle.uss に追加していますが、UI Builder で直接編集して、PopupStyle.uss を上書きすることも可能です。優先順位のルールはこちらにあります。

メニューに表示される色をすべて変更したいが、ゲームの他の部分はそのままにしたいとします。UGUI では、すべてのコンポーネントの色を 1 つずつ手動で編集する必要があります。しかし、私たちの例を考えてみてください。いま Quit ボタンだけがプレハブですが、すべてプレハブにして、ローカルで一度上書きできるようにすることも可能です。そうしておけば、それらのプレハブを編集を編集してプレハブで色を変えても、メニューの要素については無視されるようになります。

UI Toolkit では、PopupStyle.uss のタグを複製した NewStyle.uss を作成し、PopupStyle.uss を NewStyle.uss に置き換えるだけでよいのです。

シーンに UI を追加する

UXML ファイルの作成とスタイルの設定が完了したら、最後に実際のシーンに追加します。これを行うには、Scene Canvas 要素を置き換え、UI Document 要素を持つ空のゲームオブジェクトを作成します。これに popup.uxmlPanel Settings ファイルを割り当て、再生ボタンを押して新しい UI をテストしてください。

UI Toolkit を今すぐ試す

UI Toolkit をお試しいただいた後は、UI フォーラムでご意見をお聞かせいただくか、公式のドキュメンテーションで詳細をご確認ください。

最後に、私たちの新しい Unity プラットフォームロードマップにアクセスして、最新のアップデートをご確認ください。皆さんの声を直接製品チームにお伝えください。

この記事は、Unity の上級ソフトウェア開発者からなる Accelerate Solutions チームの Marina Joffrineau が執筆しています。Accelerate Solutions チームは、あらゆる規模のゲームスタジオに対して、コンサルティングとカスタム開発ソリューションを提供しています。Unity Accelerate Solutions の詳細と、Unity が皆さんの目標達成をどのように支援できるかについては、私たちのウェブサイトをご覧ください。

2022年4月20日 カテゴリ: Engine & platform | 20 分 で読めます

Is this article helpful for you?

Thank you for your feedback!