Unityの次世代UIシステムとして登場したUI ToolkitもUnity 6でその機能やワークフローの基礎がようやく固まった、と私は感じました。そこで、気持ちを新たにその基本や注意点をシンプルにまとめておこう、というのが今回の趣旨です。とは言え、本記事は4800文字ほどの内容であり、やっぱUI Toolkitって難しいんじゃ・・・と思われるかもしれません。
しかし、Unity 6で改めて触ってみると、そんなに難しく考える必要なかったなと感じました。今までちょこちょことUI Toolkitは触ってきており、Unity 6を機に本格的にUIを作っていこうと思いながら最近色々と試していましたが、思ったよりもUI Toolkitはもっとシンプルに考えてよいツールだったのです。ただし、やはり『慣れ』は必要ではあります。
問題は慣れるまでにどれくらい掛かるのか?ということで十時間?数十時間?その時間を費やす価値あるのか?そして、WebテクノロジーをベースにUI Toolkitは開発され、HTMLやCSSの経験を活かせるという触れ込みですが、逆に言えば、それらの経験がないとむしろ参入障壁になるのではないか?という問題もあります。
自分はHTMLとCSSについては最低限の知識があり、そしてUI Toolkitについても勉強に時間をそれなりに取ってきました。今となってはその価値は十分にあったな、というのが私の意見です。
しかし、今回の記事で書く注意点や、ワークフローを押さえればより短い時間でUI Toolkitの良さを理解できるようになる、はず!という想いで書いています。今回想定するケースはUI Toolkitでゲーム中のUI、つまりランタイムUI作成です。
UI Toolkitを使ったインスペクターのカスタムについては上記の記事でやっていますので参考になれば。
注意点について(むしろ本編)
重要な注意点について先にまとめます。むしろ、この注意点こそが今回のメインコンテンツかもしれません。危険な落とし穴です。逆にここをしっかり押さえておけば、UI Toolkitをよりシンプルに考えることが可能になります。
UXMLはUI構造、USSはスタイリング
これは基本中の基本ですので一応書きます。UXMLファイルはUIの構造を定義します。UI Builderを使ってUI作成するならば直接UXMLを読み書きする必要は無いです。USSはスタイルシートであり、id(要素につけられた名前)やクラスなどをセレクターとして使用して、各プロパティのスタイリングを列挙したものです。
問題はUXMLファイルは、UXMLドキュメントやらUI Document、VisualTreeAssetなどと様々に呼称されていることです。しかし、基本的にこれらは同一のモノであり、解釈の仕方が違うというだけなはずです。UI Documentコンポーネントは、UI Document(UXML document)をMono Behaviourと結びつけ、Scene内に読み込むためのコンポーネントということになります。
Inlined Styleに気をつける
特にInlined Styleに注意してください。Inlined StyleとはUXMLファイル内に直接書かれたスタイリングであり、これは優先順位が一番高いために、クラスで指定したスタイルを上書きしてしまうという事態を引き起こします。
この挙動は画面上のUIの見た目からでは分からないため、例えば、.input-buttonというクラスで背景を黒にしたのに画面ではそれが反映されない、なんで!?ということになります。
Inlined StyleとなったプロパティはUI Builderのインスペクター上で左側に白い帯が表示されます。その意図が無い場合は右クリックで、Unsetを実行して解除する必要があります。Unset Allは全てのプロパティをリセットするので注意。
Extract Inlined Styles to New ClassはUXML内のInlined stylesを新しいクラスとして切り出す機能です。これを使って、試行錯誤したスタイリングをクラスとしてUSSに追加することができます。また、これは疑似クラスによる変化形などを設定するときにも便利です。(基本クラスを付加してある要素のインスペクター上でスタイリングして、Extract...で変化形として切り出す)
クラスは識別子としてもスタイリング指定にも使える。
UI Toolkitにおけるクラスはその要素の定義するのに使ったり、またはAddToClassListやRemoveFromClassListなどのメソッドを使って、要素にクラスを着け外しすることでスタイリングを変化させることが出来ます。
例えば、UI上に複数のカードが表示される場合、それらにitem-cardというクラスを付与することで何らかの一括処理を行うことが出来たりします。
(UI Builder上ではUSSの欄からクラスをヒエラルキーやプレビューの各要素にドラッグ&ドロップすることでクラスを適用することが出来ます)
Flex-box Layoutの特性を理解する。
Flex layoutとは要するに、ヴィジュアル要素にUI上で与えられるスペースに対して柔軟にその大きさを変える能力を与える、というレイアウト・システムです。Flex containerとFlex itemのふたつがあると考え、アイテムの大きさを変えたり、アイテムの量に応じてコンテナの大きさを臨機応変に変える、などということです。
まぁこれが慣れるまではどういう挙動になるかイメージしにくい!という課題はあります。FlexプロパティのShrinkとGrowで、この伸び縮み能力を設定します。
パネル・セッティングでスケールモードを設定する。
Flex layoutは前述したように画面の大きさや解像度などの状況に応じて、UIを適切に対応させるというものです。UI DocumentコンポーネントでUXMLを設定する際にPanel Settings(パネル・セッティング)も同時にアサインしますが、パネル・セッティング上のスケール・モードをScale With Screen Sizeに設定する必要があります。これを設定しないと、Flex layoutとして作っても上手く伸び縮みしてくれません。
またパネル・セッティングは同時に複数のUI Documentで使いまわすことができ、共有するUIは同じコンテキストとして扱われます。
Unity公式のサンプルやデモが少し複雑すぎる
これはある意味で最大の落とし穴だと思うのですが、Unity公式によるUI Toolkit関連のサンプルやデモがやや難しく考えすぎなんですよね。もっとシンプルに考えて、単純で実践的な例を出せばいいのにと思います。だから、今後の本ブログではもっと単純な例を出せていきたいです。
・・・と、だいぶ注意点が長くなってしまいましたが、逆にこれらを押さえておけば混乱することはなくなるはずです。
シンプルに考えよう!
ではUI ToolkitでランタイムUIを作るにはどうすればいいか、をシンプルにまとめたいと思います。以下の10個の箇条書きされた工程を順にやっていくだけです。
UI ToolkitでゲームUIを作るワークフローチャート
- UI DocumentアセットをCreateメニューから作り、ダブルクリックでUI Builderを開き、視覚的にUIを組み立てる。
- UIが出来たらシーンに空のGameObjectを追加して、UI Documentコンポーネントを追加する。
- UI DocumentコンポーネントにUXMLファイルとパネル・セッティングを設定する。パネル・セッティングのScaleモードを設定しておく。
- UIをコントロールするスクリプトをそのゲームオブジェクトに加えるか、そのUIを使う他のゲームオブジェクトのスクリプトにSerializeFieldのUI Document変数を追加し、UI Documentコンポーネントを持つゲームオブジェクトをアサインする。
- UIをコントロールするスクリプト上で、UI DocumentをGetComponentしてそこからrootVisualElementにアクセスする。rootVisualElementとは要するにそのUXML全体のことであり、これによりUXMLで定義されたUI構造への参照を得ることが出来る。ここでは_rootという変数に入れることにする。
- この_rootからQ<>というメソッドを使うことで、目的のビジュアル要素を名前(id)やクラス名から獲得する。_root.Q<Button>("SubmitButton")
- その参照をC#上のButton, Label, ProgressBarなどの各タイプの要素に代入することで、C#上の処理をUIに反映されるようにする。
- RegisterCallBackなどを使い、その要素をクリックした時などの各イベントに対する挙動を設定する。
- あるいはその要素のSetBindingメソッドを使い、そのスクリプト上のデータとUIを結び付け(Binding)、そのデータが変化した時に自動的にUIも更新されるようにする。
- ゲーム中の処理として、AddToClassListやRemoveFromClassListを使うことで要素に含まれるクラスを変化させることでスタイリングを変化させる。
というわけで文章だけ書きましたが、実はもうこれだけのことなんですよね。少し長いリストですが、それぞれやっていることはシンプルです。性質上、UI Toolkitに関するコードはどうしても長くはなってしまうのは、UI Toolkitを難しそうに見せてしまう所ではあると思います。
UI Builder(か、以外の方法)でUIを作る。UI Documentでシーン上にUIを読み込む。rootVisualElementにアクセスする。そこからQ<>で必要なヴィジュアル要素の参照を得る。それを使って、C#スクリプト上で要素に各種設定をする。
これだけなんです。シンプルに考えましょう!
データ・バインディングは新しい機能ですが、使ってみるとかなり簡単にUIの挙動を設定することが出来て驚きました。UI Toolkitのデータ・バインディングについては、記事を今書いています。少々お待ちください。
まとめ
というわけで、Unity 6からUI Toolkitに触ってみようと思う人の指針になれば幸いです。個人的にはもうUnity UIを使う機会はほとんど無くなると思っています。
今後のUI Toolkitの予定としてはオーバーレイではない、ゲームワールド内のUIにも対応するということで、それはまた波乱があるかもしれませんが、いわゆるHUD(ヘッドアップ・ディスプレイ)はもう既に十分な状態になっていると思いましたし、自分も色々なタイプのUIを作って試している段階です。
UI Toolkitを使いこなせるようになるために、少し回り道になるかもしれませんが、HTMLやCSSを勉強してみるのもいいかもしれません。個人的にはHTML, CSSを少しでも触っていた経験が役立っているのが嬉しいのですが、かえってUI Toolkitの弱点にもなっているのかもしれませんね。
というわけで、UI Toolkitについての話題は今後も積極的にブログに書いていこうと思います。