みつまめ杏仁

アンリアルエンジン(UE4)でGUIを作るためにゴニョゴニョしてます。UIデザイナーの皆様の助けになれば幸いです。

スコア表示のときに

 ふと思いついて作ってみたシリーズ。

 よくスコアの表示などにゼロ埋めとかゼロパディングとかいう表記法を見かけます。あらかじめ最大桁数を晒すということは、桁が埋まらないうちはプレイヤーの非力さを示し、埋めていたゼロが無くなってくると今度はカンストを示すことになるので、それとなくネガティブな印象を与えてしまうことがあります。ゲーム画面のデザインで桁の多い数字を表示する場合はその辺も考慮しつつデザインを考えることになります。

 もとはデジタルな計器などのインジケーターに良く使われる LED(7セグ) や VFD(蛍光表示管)、電卓の液晶、古くはピンボール台のニキシー管等々、物理的なレイアウトの制限によって最大表示桁数が設けられているのをデザインモチーフとして利用している、そんなところでしょうか。ニキシー管カッコイイですよね。確かシュタゲでも登場していたような。ニキシー管が何か気になる人は  nixie tubes で画像検索してみてください。

 

 ゲームのUIとしては、ただ数字を表示するだけでは、何の値か分からないので一緒に見出しを付けます。ゼロパディングはその見出しとの距離を縮めてくれる効果もあります。距離が近い方が視線の流れが易しくなります。

 

f:id:hiyokosabrey:20200128013051p:plain

 

f:id:hiyokosabrey:20200128013055p:plain

 

 

今回のネタはこのゼロパディングの部分を分けて表示します。

 

 f:id:hiyokosabrey:20200128013718p:plain

 

これをHorizontalBoxを使ってやってみます。

まずはキャンバスに HorizontalBoxを一つ。

f:id:hiyokosabrey:20200128215130p:plain

 

中に TextBlock を 2つ入れます。ヒエラルキーはこんな感じ。

f:id:hiyokosabrey:20200128224209p:plain

 

それぞれ適当にゼロを入れておいてカラーを調整。

f:id:hiyokosabrey:20200128220505p:plain

 

デフォルトだと左詰めなので、右詰めになるように設定を変えます。

(さくっとうまくいかなくて以外にややこしかった)

f:id:hiyokosabrey:20200128224213p:plain

f:id:hiyokosabrey:20200128224216p:plain

 

ここからはブループリント。

 

まずは変数を4つほど用意します。Integer型が3つ、String型が1つ。

f:id:hiyokosabrey:20200128230354p:plain

 今回桁数は最大8桁にするので、digit_max の初期値は 8 を。

f:id:hiyokosabrey:20200128231219p:plain

digit_string_zero の初期値はゼロを 最大桁数より1つ少ない 7桁分入れておきます 。

f:id:hiyokosabrey:20200128231223p:plain

 

次に、スコアをTextBlockに反映する関数を用意します。

f:id:hiyokosabrey:20200128231646p:plain

ゼロ埋めする数を事前に計算している前提。

 

 カスタムイベントでスコアを受け取るようにする。先に作った関数は右下につないでます。

f:id:hiyokosabrey:20200128233547p:plain

桁数を調べるのは、対数関数の log を使ってみました。いったん文字列型にキャスト(型変換)して文字数を調べる方法もあるけど、キャスト処理のコストが高いのでやらない方向で。

 対数関数は、底(BASE)を 10 にすることで、10進法での桁数が分かるというものです。

 ざっくりとした説明ですが、例えば桁を表す百の位の 100 は10の2乗、万の位は10の4乗です。つまり乗数は桁数より1少ない数であることに気づくと思います。この乗数で表わされるのを指数、その逆である対数というものが log で表わされるそうです。

 本来の用途ではない気がしますが、ちょっと気になったので log で出てくる数字を調べてみました。

 参考までに、65535 という数字を log ノードに入力してみると、 4.8164733037652... という値が出てきます。それをInt型の変数にキャストする際に自動で挿入されるTrancateノードによって 4 という数字になります。99999 という数字なら、4.999995657... となって、10000 だと 4 、100000 だと 5 になります。

 ということなので、使う際には +1 します。また、log に0は無効なので、ブランチノードで0以上かどうか判定してから渡しています。

 

できました。

f:id:hiyokosabrey:20200129002011j:plain

 0~9の文字幅が揃ったフォントだといい感じです。

 

カウントアップのアニメーションを試してみました。

f:id:hiyokosabrey:20200129230716g:plain

 

文字幅に差があるフォントの場合。

f:id:hiyokosabrey:20200129231511j:plain

Neuropolはお気に入りなんですが、極端に1の幅が狭いです。

 

アニメーションするとガタガタします。 

f:id:hiyokosabrey:20200129231929g:plain

 

今回の方法を使わずに、重ねてしまうのもアリかもしれません。ニキシー管ぽくなります。

f:id:hiyokosabrey:20200130003753g:plain

 

 

これで完成ですが、ちょっとだけブループリントをいじります。

スコアをTextBlockに反映するために作った関数があります。

f:id:hiyokosabrey:20200129235047p:plain

 実は、後から Collapse Function して作ったものです。スッキリして悪くないと思うのですが、中でどんな変数が使われているか、中を確認しないと分からないので、関数を作った本人以外はモヤモヤしそうです。

 これをわかりやすくする方法があります。わざと中の変数をパラメータとして渡すようにします。

 

 結果がこれ。

f:id:hiyokosabrey:20200129235845p:plain

 

f:id:hiyokosabrey:20200130000445p:plain

 これで何の変数を使って処理しているか分かるので、処理をイメージしやすくなります。つなぐ手間は増えますが、関数名だけのノードよりわかりやすくなると思うのですがいかがでしょうか。関数の汎用性も向上するのでオススメです。

 

ではでは

ステキなスコア表示ライフを!