土鍋で雑多煮

UnityでXR・ゲーム開発をしています。学んだことや備忘録、趣味の記録などを書いていきます。

MENU

【Unity】UI ToolkitでUIを構築してみる

はじめに

どうも、土鍋です。

今まで気になってたけど触ってなかったUI Toolkitを触ってみました。

Unity6になって以前より使いやすくなり、機能も今後更に増えるようです。

内容は以下の動画とほぼ同じですが、プラスアルファでやってみたことを書いてます。

www.youtube.com

UI Toolkitとは

UnityのUIは「Unity UI (uGUI)」「IMGUI」 、そして最新の「UI Toolkit」の3種類が提供されています。

uGUIはいわゆるCanvasを作ってUIを作っていく一番メジャーな方法で、
IMGUIはUnity Editor拡張を作るときに利用しているものです。

UI Toolkitはそこに加わった新しい手法で、Web開発の概念が組み込まれ、かなり近代的手法で合理的にUIを構築できるようになります。

UI Toolkitをやってみる

UI ToolkitでのUI構築に必要なものを作ります。

Create > UI Toolkit > UI Document

Create > UI Toolkit > Panel Settings Asset

この2つが最低限UI ToolkitでのUI構築に必要です。

適当に作った空のオブジェクトにUI Documentコンポーネントに作ったUI DocumentとPanel Settings Assetを設定。

UI Builder

UI DocumentをダブルクリックするとUI Builderが開かれます。

Libraryから置きたいUIコンポーネントを選択し、ヒエラルキーorViewportにドラッグ&ドロップしてUIをデザインしていく。

これだけで自動的にxmlが生成される。

親子構造やAline、Size、Spacingをいい感じに調整して画面を作る。

Position Mode

Relative: 同階層のVisualElementは自動的に並ぶ。
Absolute: 階層に関係なく配置できる。重ねて配置する必要がある場合はこれ。

UIに実際の処理を追加する

コンポーネントに名前をつけることでスクリプトから指定できるようになる。

ボタンを押したときの処理は以下のように書ける。

using UnityEngine;
using UnityEngine.UIElements;

public class UITest : MonoBehaviour
{
    void Start()
    {
        var root = GetComponent<UIDocument>().rootVisualElement;

        root.Q<Button>("button-test1").clicked += () => Debug.Log("test1");
        root.Q<Button>("button-test2").clicked += () => Debug.Log("test2");
        root.Q<Button>("button-test3").clicked += () => Debug.Log("test3");

        root.Q<Button>("send").clicked += () => Debug.Log(root.Q<TextField>("textfield-test1").value);
    }
}

StyleSheets

WebでいうCSSにあたるものとしてUI ToolkitではUSSというものがあります。 よく使うコンポーネントをクラスとして保存して変更を容易にするものとして使われています。

左上の+ボタンから新しいUSSを作ります。

適当な名前をつけてクラスを作ります。

作ったクラスをボタンにドラッグ&ドロップで適用できる。
ボタンのインスペクターのStyleSheetを見ると適用されているのが確認できる。

作ったクラスを選択し、値を変更するとそのクラスを持つコンポーネントも変更される。

アニメーション

左上の+からホバー時のアニメーションのためのセレクターを追加する。

TransformのScaleを少し大きくする。

Previewを押して、確認するとホバー時にボタンの大きさが変わっているのが確認できる。

アニメーションを付けるにはTransitionAnimationsから何秒でどのプロパティの変更をどんなEasingでアニメーションするかを設定できる。

戻るときにもアニメーションを付けたいのでホバーではない方のセレクターを選択し、同様にTransitionAnimationsを設定してあげる。

今の設定を保存する

data binding

Listの要素のためのUIを作る。

それぞれの要素に紐付いたScriptableObjectを作る。

using UnityEngine;

[CreateAssetMenu(fileName = "MovieCard", menuName = "Scriptable Objects/MovieCard")]
public class MovieCard : ScriptableObject
{
    public Texture2D thumbnail;
    public string movieTitle;
    public string channelName;
}

ScriptableObjectと紐づける

一番上の階層のVisualElementを選択し、Data SouceにScriptableObjectをセットしてあげる。

BindしたいVisualElementの項目を選択し、3点ボタンor右クリックでメニューを開いてAdd Bindingを押す。

Data Source PathにScriptableObjectのプロパティを選択することができる。

正しく設定できると画像のようにScriptableObjectの内容に沿ったものが反映される。

別のScriptableObjectを設定すれば内容も変わる。

ListView

ListViewを追加したら、
ItemTemplateに先ほど作ったUI Documentを設定する。
BindingSourceSelectionModeをAuto Assignにする。

リストに追加するデータを指定するためのScriptableObjectを作る。

using UnityEngine;

[CreateAssetMenu(fileName = "MovieList", menuName = "Scriptable Objects/MovieList")]
public class MovieList : ScriptableObject
{
    public MovieCard[] movieCards;
}

リストビューのitemsSourceに作ったScriptableObjectからデータを流し込む。

public class UITest : MonoBehaviour
{
    public MovieList movieList1;

    void Start()
    {
        var root = GetComponent<UIDocument>().rootVisualElement;

        root.Q<ListView>("movie-card-list1").itemsSource = movieList1.movieCards;
    }
}

色々調整して、試しにY◯utube風のUIを作ってみました。

※実はGridLayoutのテンプレートがないので、リストを2つ並べている。

まとめ

uGUIはUI作るには若干使いづらい節があったんですが、UI ToolkitはかなりUIを構築しやすくなりました。

特にWebなどで使われる概念を取り入れたことでFigma等との連携が取りやすくなったのがとても嬉しい点かなと思います。(UnityだとFigma通りに作るのが一苦労だった。)

ですが、uGUIではできたShaderの設定や複雑なアニメーションの設定、world spaceでの利用ができないので、これらを使う必要がある場合はまだuGUIを使う方が良いと思います。

参考

youtu.be

youtu.be

youtu.be