原カバンは鞄のお店ではありません。

Unityを使ったゲーム制作のあれこれを綴っていきます。

【Unity】Unityの最新のUIシステム「UI Toolkit」

都知事選

地方の人も首都の首長を決める選挙には関心を持ってドンドン発言すべき、という意識高いポストを無関心の目で読んでいた地方民の皆さんこんにちは。この話題に一切触れないアカウントに違和感を感じる、とか意味の分からないポストも飛び交っていましたが、何はともあれ一段落したようで良かったです。ゲーム関連のアカウントしかフォローしていないはずなんですが、タイムラインが汚れて非常に目障りでした。

 

UI Toolkit

UnityでボタンやテキストなどのUI関連を実装しようとすれば、uGUIを用いる事が殆どだと思います。
uGUIはボタンやテキストをGameObjectとしてHierarchy上に配置する形式なので、ゲーム本体の2D,3Dオブジェクトと同様の扱いで実装する事ができ、レイアウトの調整もUnityエディタ上で操作できるので大変便利なのですが、一方で同じようなデザインでパターン異なるUIを量産したい時などは各オブジェクト毎に変更が必要なので、ノベルゲームのような大量のUIを必要とするゲームには不向きな形式でした。
その為か、UnityではuGUIの他に、新しいUIシステムとしてWeb系のシステムでは多く採用されているHTML/CSSライクなUIの設計手法を取り入れた「UI Toolkit」というシステムが提供されています。

docs.unity3d.com

UI Toolkitでは基本的にテキストベースのUXMLSを編集してUIを作成する事になりますが、HTML/CSSと同様にそのデザイン(スタイル)をUSSとして使い回すことが出来る事が大きな点で、theme style sheet(tss)というテーマとして共通で使いたい値やスタイルが定義されているussをまとめたスタイルシートを作ることでプロジェクト全体でデザインを共有しながら一部をオーバーライドしたバリエーションテーマを作成する、ということも可能となります。

 

UI Builder

UXMLSを編集してUIを作成すると説明しましたが実際には専用のエディタ「UI Builder」が用意されており、そちらを使いながらUIのデザイン作業を行います。
メニューバーから「Window->UI Toolkit -> UI Builder」とクリックすると、UI Builderのウィンドウが立ち上がります。

UI Builderは上のような画面構成になっており、まず最初にVisualElementを作成するため、左下の「Library > Containers」の中から「VisualElement」を右側のViewportにドラッグ&ドロップして追加します。

すると上のように左中央の「Hierarchy」に「VisualElement」が追加され、その下に「Library > Controls」から「Button」やら「Label」を選んで追加して行くことでUI画面をデザインしていきます。

 

ButtonやLabelを配置し終えたら、Ctrl + S (Winの場合) で保存すると指定したディレクトにuxmlファイルが作成されます。

今回はボタンを設置しただけのデザインを「SimpleButton」という名前で保存しました。

 

レイアウトの編集

UIのレイアウトを変更する場合はUnityのProjectウィンドウから、先程保存したuxmlファイルをダブルクリックすると再びUI Builderが立ち上がります
Hierarchyから 、Element(ボタンらラベル)をクリックすると、右側にInspectorが表示されるで、こちらを変更してElement要素の各属性を指定します。

今回は先程のデザインからViewElementのサイズ、背景色を変更してラベルを追加、ついでにボタンの背景色も変更しました。

作成したUIをゲーム空間内に配置するにはUnityエディタのHierarchyウィンドウ内で右クリック→UIToolkit->UIDocumentを選択して「UIDocument」コンポネントがアタッチされたGameobjectを作成します。

Inspectorウィンドウから Source Asset のフィールドに先程作成した uxmlファイル をドラッグ&ドロップしてセットします。

するとゲームビューに先程作成したUIが表示されていることを確認できます。

 

スクリプトから生成、変更

そのままでも使用することが出来ますが、スクリプトによる生成、変更を行うためにUIDocumentを一旦ProjectウィンドウへドラッグしPrefab化します。
その際、UI Builderから各Elementの「右クリック→Rename」で名前をスクリプト側で指定しやすい名前に変更します。(先頭の#は勝手につけられるので名前の部分のみを変更します)

 

Prefab化したUIDocumentはスクリプト側でInstantiateで生成する事でシーン内に自動で配置されます。

public class UIController : MonoBehaviour
{
    [SerializeField] GameObject SampleButtonPrefab;
    private UIDocument _uiDocument;

    void Start()
    {
        // PrefabからUIを生成
        var buttonObject = Instantiate(SampleButtonPrefab);
        
        // UIDocumentの参照を保存
        _uiDocument = buttonObject.GetComponent<UIDocument>();
    }
}

ボタンクリック等のイベントを受け取る場合はUIDocumentのrootVisualElementから、Q<T>関数でボタンのElementにアクセスします。ここら辺はjsp辺りと同じような実装になっています。

例えばボタンクリックのイベントを受け取る場合は以下のようにコーディングします。

var buttonElement = _uiDocument.rootVisualElement.Q<Button>("FormButton"); // 引数にVisualElementの名前を指定
buttonElement.clicked += () => { /* クリック時の処理 */ };

 

サイズや位置の変更もrootVisualElementから、Q<T>関数でプロパティにアクセスして変更します。

// 操作対象のVisualElementを取得 (※ rootVisualElementは基本的に不適当)
var baseElement = _uiDocument.rootVisualElement.Q<VisualElement>("Base"); // 引数にVisualElementの名前を指定

// UI のサイズ変更
baseElement.style.width = 200; // UIの横幅を変更
baseElement.style.height = 200; // UIの縦幅を変更

// UIの位置変更
baseElement.transform.position = new Vector3(200f, 100f, 0); // UIの座標を変更

 

実装例として今回はボタンクリックでラベルに「Clicked!」の文字を表示する処理を組んでみました。

   void Start()
    {
        // PrefabからUIを生成
        GameObject documentObject = Instantiate(SampleButtonPrefab);

        // UIDocumentの参照を保存
        _uiDocument = documentObject.GetComponent<UIDocument>();

        // ボタンとラベルのコントロール取得
        var buttonElement = _uiDocument.rootVisualElement.Q<Button>("FormButton");
        _labelElement = _uiDocument.rootVisualElement.Q<Label>("FormLabel");

        // ボタンクリックイベントの購読設定
        buttonElement.clicked += OnClick_Button;
    }

    private void OnClick_Button()
	{
        _labelElement.text = "Clicked!";
    }

動作はこんな感じ

 

最後に

今回はUI ToolKitの使い方について基本的な部分を紹介しました。前述のようにHTML/CSSライクなUIの設計手法を取り入れている為、既にWeb系のシステム開発に従事している方にとっては馴染みがあり導入が容易いかと思います。

また、uGUIと比べスクリプトさえ作っておけば、uxml/ussを差し替えるだけで要素を増減したり、見た目を変えたりすることができるため、規模の大きなプロジェクトでは設計・管理がしやすいシステムだと思うので、今後はUI ToolKitを使った開発案件が増えていくのではないでしょうか。

◇プライバシーポリシー

●個人情報の利用目的

当ブログでは、メールでのお問い合わせ、メールマガジンへの登録などの際に、名前(ハンドルネーム)、メールアドレス等の個人情報をご登録いただく場合がございます。

これらの個人情報は質問に対する回答や必要な情報を電子メールなどをでご連絡する場合に利用させていただくものであり、個人情報をご提供いただく際の目的以外では利用いたしません。

●個人情報の第三者への開示

当サイトでは、個人情報は適切に管理し、以下に該当する場合を除いて第三者に開示することはありません。

・本人のご了解がある場合
・法令等への協力のため、開示が必要となる場合

個人情報の開示、訂正、追加、削除、利用停止
ご本人からの個人データの開示、訂正、追加、削除、利用停止のご希望の場合には、ご本人であることを確認させていただいた上、速やかに対応させていただきます。

アクセス解析ツールについて

当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。

このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。

●免責事項

当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。

当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。

当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。

●プライバシーポリシーの変更について

当サイトは、個人情報に関して適用される日本の法令を遵守するとともに、本ポリシーの内容を適宜見直しその改善に努めます。

修正された最新のプライバシーポリシーは常に本ページにて開示されます。