![見出し画像](https://assets.st-note.com/production/uploads/images/162378345/rectangle_large_type_2_2e06427e126eaaa4d779ea0ae3c1869d.png?width=1200)
MGL週報 #70 - MGLのUIあれこれ
このエントリはゲーム開発用フレームワーク「MGL」の開発記録です。MGLはzlibライセンスの下に無償で提供されています。
ドキュメントはこちら
進捗状況の確認と問い合わせはこちら
MGLのUIあれこれ
MGLにはUI実装補助機能というものが存在していて、これは実装済みでありながらドキュメント化が済んでおらず、細かい検証も済んでいない状態にあります。これは今年の初め頃に作業タスクに積んだまま放置されており、そろそろ対応しないと実装内容を忘れそう……と言うか、現時点でもう色々忘れかけています。
UI機能の検証用に、ほぼUIのみで成立する小規模なミニゲームを実際に作ってみるのもありかな……と考えていたところ、ふと思い出した事があったので話のネタにご紹介します。
「ぺぐそり+」のUI構想メモ
次の画像は「ぺぐそり+」がまだ私の頭の中にしか存在していなかった頃に描いたものです。
![](https://assets.st-note.com/img/1731939699-wFAikqfDn40alcS5HGgt9OR8.png?width=1200)
![](https://assets.st-note.com/img/1731939744-Ln29ZrW0TSogzbXhU3RwqA7V.png?width=1200)
ピクセル単位の寸法まで書かれていますが、これは資料として作った訳ではなく頭を整理するために取ったメモ書きです。寸法は「どれくらいのフォントサイズが最適か」とか、「素材に使用する画像の解像度はどれくらいが良いか」といった感覚を掴むために付けたものです。
本当はちゃんと資料化するのが正しいのかもしれませんが、この手の内容は古くなりやすいため資料として管理するのもコストが高いのですよね。なので、私はあまりきちんと管理せず、メモ程度にパッと作っては捨ててを繰り返しています。この画像ももう捨ててしまったかと思っていましたが、古いリポジトリのバックアップデータの中に運良く残っていました。
ちなみに、実際にリリースされた画面はこちら。
![](https://assets.st-note.com/img/1731939844-JKjDg7Unw2HlATthadkziWYv.png?width=1200)
大まかには一致していますが、細かい部分での差異が確認できると思います。
さて、今回お話したいのは当時の回想ではなく、この構想メモからどのようにして実際に動くUIに落とし込むのかというお話です。
「ウィジェット」という概念
ゲームのUIの実装に慣れていないうちは、画面を構築する際にまず画像や文字を表示して、そこに選択や遷移といった制御を加えるといった手順を踏みたくなるかもしれません。その方法でも大きな誤りではないのですが、中間にもう1つ要素を加える事によってUI実装は格段に容易になります。
その要素とは、UIを「部品化」する事です。画像や文字で直接画面を構築するのではなく、一旦UIの構成要素となる「部品」を作ります。この部品を組み合わせる事で、別の部品を作ることもできます。それらを組み合わせていくと、最終的に「画面」が出来上がります。
このUIにおける「部品」の事は、一般的に「ウィジェット」(widget、ウィジットとも)と呼ばれています。Wikipediaにちょうど良い記事があったのでリンクを貼っておきましょう。
ウィジェット化のメリットは、1つ1つのウィジェットは小規模なため実装しやすく、それを組み合わせるのも容易である事です。加えて、何かしらの変更を加える際にもウィジェット単位で問題を切り分けて考えられるため、仕様やデザインの変更にもある程度対応しやすいと言えます。
よく使うウィジェットをまとめたものは「ウィジェット・ツールキット」と呼ばれ、GUIを備えたOSには専用のツールキットが用意されています。このため、一般的なGUIアプリケーションの開発ではウィジェットそのものを作成する機会はそう多くはありません。
しかし、ゲームの場合は独自のUIを持つ事が多く、既存のウィジェット・ツールキットに頼りにくいという事情があります。これがゲーム開発と一般的なアプリケーションの開発との大きな差の一つと言えるでしょう。(ゲームエンジンがウィジェット・ツールキットを備えている事もありますが、そっちはそっちで別のノウハウを持つ世界ですのでここでは割愛しましょう)
先ほどの構想メモを書いた理由の一つは、そのゲームを作るにあたってどのようなウィジェットを要するかを大雑把に見積もるためでもありました。そして、一度ウィジェットとして切り分けてしまえば細かい調整や変更も柔軟に行えるため、描いた内容はどんどん古くなります。故に資料ではなく使い捨てのメモとして作成していたのです。
ウィジェットを組み合わせたウィジェット
さて、既にチラリと書きましたが、ウィジェットの特徴の一つはウィジェットを組み合わせて別のウィジェットを作成できるという点です。これはとても重要な事ですので、例を用いてざっくりと説明を……ん?
あれ? これ前にやらなかったっけ? と思って調べてみたら、以前の週報でも書いていました。
せっかくなので該当記事の画像を再び用いて説明しましょう。次の2つは、「ぺぐそり+」の設定ウィンドウのスクリーンショットと、その構成をウィジェット単位に分けた図になります。
![](https://assets.st-note.com/img/1731939948-p5c9RzeLv3tTS4Dd1Eoi8rKQ.png?width=1200)
![](https://assets.st-note.com/img/1731939981-Hu4lVSMQLJi9Pxkqj2YXBGbm.png?width=1200)
今回注目して欲しいのは、値選択ウィジェットはテキストウィジェットとボタンウィジェットの2種類から成り立っているという点です。このウィジェットは、名前の文字列と変更可能な値の範囲(もしくはリスト)を受け取り、2つのボタンによってその内容を変更する機能を持っています。現在選択中の値はもちろん、切り替わったタイミングもコールバックとして認識可能です。
クリック判定やテキスト表示といった処理は値選択ウィジェット側では行っておらず、各々のウィジェットにお任せしています。これにより、値選択に必要な機能のみに特化した実装になっています。
また、親である設定ウィンドウから見た場合、値選択ウィジェットは選択可能な値を返す1つのウィジェットに過ぎません。したがって、内部の実装がどのようになっていても(例えばプルダウンに変更したりしても)親はその変更の影響を受ける事はありません。
そして、この設定ウィンドウもまた独立した1つのウィジェットでもあります。このため、シーンや画面という枠に囚われる事なくどこでも配置可能であり、実際に設定ウィンドウはゲーム中にどこからでも開けたりします。
各々のウィジェットをどの単位まで切り分けるかは一概に最適解を出せる問題ではなく、なかなか奥の深い世界です。そのウィジェットに直接実装するか、別のウィジェットに分けるべきかといった感覚は、プログラミングにおけるサブルーチンに分けるか否かの問題に共通しているかもしれません。
MGLにおけるUI実装補助機能
さて、MGLの話に戻りましょう。と言っても、もう何となく想像は付いているかもしれません。
MGLに実装されているUI実装補助機能とは、要するにUIウィジェットを実装するための機能です。
UIのウィジェット化は多数のメリットがありますが、メリットしかない手法など私の知る限り存在しません。UIウィジェットは作ったり組み合わせたりは簡単ですが、それを上手く動作させる仕組みまで作るとなると一筋縄ではいかなくなります。そこで、その面倒な部分をMGL側が吸収しようというのがこのUI実装補助機能です。
UIウィジェットが要する機能は大まかに次の通りです。
ウィジェットは親子関係を持ったツリー構造になっており、子は位置などの親のパラメータを引き継ぐ
ウィジェットは入力などのアクションに応じてイベントを発行し、その内容を外部に伝える必要がある
このうち厄介なのは2の、ユーザー入力に対して適切なアクションを取る仕組みです。何故なら、ゲームというのは操作デバイスが統一されていないためです。
コンソールならゲームパッドが標準的ですが、PCならマウスとキーボードが、スマートフォンならタッチパネルがそれぞれ標準的なインターフェースとなっています。AppleTVのようなリモコン型のタッチデバイスもあれば、VRではトラッキングによる操作も行われています。
これらの操作方法の違いは、最適なUI/UXの違いを生み出します。それに伴い、見た目はもちろん、ウィジェットが発行すべきイベントやそのタイミングにも変化が生じます。これら全てを仕組みでカバーするのはもはや現実的ではなく、個別の実装に頼らざるを得ません。
このため、MGLのウィジェットはイベントに関する処理を分離してあり、各々のウィジェット単位で任意のイベント処理を適用できるようになっています。マウスとタッチ、キー操作によるカーソル移動といった標準的なイベント処理は備えてありますが、これらをカスタマイズしたり、完全新規に作成することも可能です。
また、同じゲームでも部分的にイベント処理をカスタマイズしたくなる場合もあります。その辺の詳細は次の実装当時の週報に記されていましたので、気になる方は参考にどうぞ。
ドキュメントの最初のページにも書いてある通り、MGLのコンセプトは「全てを用意はできないが、簡単に補える」です。故に、他のゲームエンジンのようにウィジェット・ツールキットそのものを提供することは当面は目指さず、まずはそれを作るための仕組みを提供します。
理想的な形はMGL向けのウィジェット・ツールキットをエクステンションとして複数提供し、作るゲームに最適なツールキットを個別に選択できるようにする事です。それはしばらく先の話になりそうですので、今は下地をしっかり固める事が最優先という状況です。
その他
UIの構想メモやドキュメントの図の作成にはmacOS向けのGraphicというソフトを使用しているのですが、これが長らくアップデートされていないため乗り換えを検討しています。Adobe Illustratorは(どうせCCを契約する事になって)お高いし、Inkscapeは少々癖が強くて色々と悩み中です。
UIのデザインツールに関しては、職場のUIデザイナーさんが使用していたFigmaを近々試してみる予定です。