【ProjectTiny0.20】TinyRacingを解析しよう!【UI編】

はじめに

ProjectTiny0.20がリリースされてからもう一ヶ月以上経過しました。
いくつか解説記事が公開されるかな?と思っていたのですが、国内ではほぼゼロというのが現状となっています。
そうなってくるともう自分で書くしか無い!
ということで今回から少しずつですが公式サンプルプロジェクトであるTinyRacingを解析、解説していきます。

TinyRacingのプロジェクトは以下のリポジトリで公開されています

Unity-Technologies/ProjectTinySamples

https://github.com/Unity-Technologies/ProjectTinySamples/tree/master/TinyRacing

実際にTinyRacingのプロジェクトを見ながら読み進めることをおすすめします。

なんで最初にUIの話?

ProjectTiny0.20 には2D機能が一切存在していないのに、TinyRacingにはUIが存在しています。
つまり、それなりに独特な実装となっています。
ゲームとしてUIは欠かせない存在だと思うので、

ProjectTiny0.20でどうやってUIを実装すれば良いの!?実装方法わからないから様子見するしか無い!

と頭を抱えている人がそれなりにいるんじゃないかなと思ったので今回、一番最初に解説しておこうと思いました。

ざっくりとした実装法について

分かる人には分かる例えで言ってしまえば

PS1のスプライト実装方法に近い

といえます。

技術的には

四角形の板ポリにテクスチャとして画像を貼り付けて描画しています

実際プロジェクトを開いてみると思いっきりワールドに設置されている
順位表示のための数字も全てマテリアルとして読み込まれている
順位表示のUI
四角のメッシュに数字のマテリアルを貼り付けていることがComponentから見て取れる

どうやって動的に順位の数字入れ替えてるの?

このあたりですが、それなりに力技になっています

UpdateUIが数字の更新を担っています

以下がそのコードです。

注目すべきはここ。36行目から50行目のエリア。

Numbersという数字テクスチャが格納された配列に対して、取得した数字をキーとしてアクセスし、対応する数字テクスチャを対象のEntityに適応しています。

なお、Numbersは別のEntityに割り当てられているComponentに最初から配列として所持するようにしています。

これに対してSignletonとしてアクセスして取得している感じです

数字のマテリアルを保持するComponent
無表示状態用のテクスチャも所持している

なお、順位やLap数などの動的にマテリアルが変更されるUIにはDynamicGamePlayMenuTagというComponentがアタッチされており、その名の通り動的UI判別用のTagとしての役割になっています。

Tagなので中には何も書かれていません。

どうやってUIから入力を受け取っているの?

ゲーム中、スマートフォンからはバーチャルパッドから入力を受け取っている

どのようにしてUIの描画をしていて、なおかつ動的に数字を差し替えているのかざっくりと理解できたかと思います。

次に、どのようにして入力を受け取っているのかを解説します

まず最初に言っておきますが…

ここ、かなり力技です

UpdateCarInputs.csが入力処理を担っています

まずは以下のコードをご覧下さい

一見、いろいろ書かれているな~と感じますがこれはマルチプラットフォーム対応のために複数の入力方式が記述されているだけなので、タッチパネルでのProjectTinyで動いているのは以下の部分のコードになります。

OnUpdate() は50行目~82行目が動いている

どこがタッチされたか認識している PressAtPositionは93行目から119行目までが動いている

何をやっているか、簡単に言い表すと

・どのあたりをタッチされているのかを計算で算出
・算出したX座標がUIを表示している位置と同じであれば入力として受け付ける

という作りになっています。

つまり、

別にUIから入力を受け取る処理が組まれている訳ではない

ということです。

X軸しか見てないので、別にペダル等のUI触る必要もないです、空あたりをタッチしてもX軸さえあってれば問題なく認識されます。

冷静に考えれば当たり前な話です。だってUIシステムなんて元から存在していませんからね。

まとめ

UIは板ポリに画像をテクスチャとして貼って描画する

動的変更は素直にテクスチャを動的に差し替えよう

UIから入力を受ける方法はない、タップされた位置を直接取得して判断しよう

色んな意味で、ゲームエンジンとは思えない原始的な運用が必要とされます。

今後このあたりは改善されていくと思いますが、今の所この方法以外はUI関係は対処できないというのが結論です。
または独自でボタンシステムを構築するといいと思います。

または、春に予定されている次回アップデートで2D機能が追加されるまで触らずに放置しておくかです。
私がもし、ボタンシステムを作ったときはGitで公開しようと思います。
今のProjectTinyはゲームエンジンというよりは、描画を担当してくれるライブラリとして捉えたほうが正しいのかもしれませんね。