みつまめ杏仁

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

クリックするだけの簡単なゲーム

 前回の記事で、パラパラとパネルを出現させるやつで遊んでたら、ビンゴカード ぽい見た目になったりしたので、さらに調子に乗ってミニゲームにしてみた。もう10年以上前?かな、一度流行ったことがあって、それの再現です。

f:id:hiyokosabrey:20190209210630j:plain

 ルールは、1~25までの数字が書かれたパネルを、順にクリックして全部クリックするまでにかかった時間を競うというものです。あぁ アレか・・・という溜息が聞こえてきそうですが、わりと手軽?に作れたので記事にしてみようかと。ただ記事的にちょっとボリュームがあるかも・・・

 

 作りはシンプルにいきます。作るWidgetは2つだけ。

 

まずは1個目のWidget。キャンバスから。

ここに 120x120の CanvasPanel を一つ。

f:id:hiyokosabrey:20190204001027p:plain

このキャンバスに対して、Image(下敷き) と TextBlock(数字)、Image(カバー用)を子供に します。

f:id:hiyokosabrey:20190204001340p:plain

ここまでは前回と同じ。

このパーツたちに対してアニメーションを用意します。

今回用意したのは以下の4つ。

 

FADE_IN

f:id:hiyokosabrey:20190207003101g:plain

最初の出現用です。この時点で数字はわかりません。

 

 

COVER_OUT

f:id:hiyokosabrey:20190207003403g:plain

ゲーム開始時に 上の FADE_IN 再生後の状態から続く感じで再生します。インパクトを出すために青いカバーを白くします。

 このタイミングで数字と下敷きを表示するのですが、ちょっとだけ仕込みが必要。

f:id:hiyokosabrey:20190209134302p:plain

このあと数字を拡大して消すときに、隣のWidgetにかぶさるとクリック判定を邪魔してしまうのを防ぐために、TextBlockだけは Hit Test Invisible を選択します。

 

 

REMOVE_PANEL

f:id:hiyokosabrey:20190207003933g:plain

クリックして順番が正解した際の演出です。数字だけを消しています。

 

 

FADE_OUT

f:id:hiyokosabrey:20190207004216g:plain

全てのパネルを消した後の演出です。

 

キャンバスはここまで。

次はWidgetブループリント。

 

まずは変数を4つほど用意。

f:id:hiyokosabrey:20190209131348p:plain

 

ちょっと色気を出すためにSlateColor型の変数を配列にします。

f:id:hiyokosabrey:20190207213121p:plain

適当に5色をセット。

 

次に値を受け取る関数を用意します。

f:id:hiyokosabrey:20190207213533p:plain

Integer型のInputピンを2つ。受け取った値は、後で別の場所でも利用するので、すぐに用意しておいた変数にお取り置きします。Indexはパネルの場所を表す値。左上が0、右下が24です。

f:id:hiyokosabrey:20190205002714p:plain

このIndex番号を %5(5で割った余り) すると、下のようになります。

f:id:hiyokosabrey:20190205003147p:plain

この計算した数値をフォントの文字カラーとして配列から引っぱり出しすと左の列から順に色が変化することになります。

 

Numberは表示するための数字です。

 

関数の次は、イベントディスパッチャーを2つ用意します。

f:id:hiyokosabrey:20190207214725p:plain

アニメーションの終了通知と、クリックされた際の応答に使うためです。

応答用のは、値を送り返すのでInputピンを2つ追加します。

f:id:hiyokosabrey:20190207214939p:plain

 

アニメーションを再生するためのカスタムイベントを用意していきます。

最初の登場演出用。

f:id:hiyokosabrey:20190209132003p:plain

出現時、まだクリックを受け付けたくないので、フラグを False にしておきます。

※このフラグは後述のマウスイベントの処理のところで活躍します。

 

このアニメーションの後に、『 Click to Start 』って出したいのでアニメーション終了通知のために、イベントディスパッチャーを呼び出し(Call)ています。

このWidgetは画面に 25個も表示するので、通知処理は最後の1個だけで十分です。前の24個は通知処理しなくてもいいので、カスタムイベントのInputピンにBooleanを一つ追加しています。

ちなみに、このイベントを呼び出す際は下のようなノードになります。

f:id:hiyokosabrey:20190207222535p:plain

 

次は、ゲーム開始のための表示演出イベント。

f:id:hiyokosabrey:20190209134805p:plain

ここから、マウスクリックを受け付けるので、フラグを True にします。

 

次は、数字がヒットして、消えるときの表示演出イベント。

f:id:hiyokosabrey:20190209135301p:plain
ここで マウスクリックを受け付けたくないのでフラグを False にします。

 

 

次のイベントは、ゲーム終了時の表示演出イベント。

f:id:hiyokosabrey:20190207224027p:plain

 

これで4つのアニメーション再生の準備は整いました。

 

最後に、マウスクリック時の処理を用意します。

関数を作るところに Override ボタンがあるのでそこから

f:id:hiyokosabrey:20190207224936p:plain

On Mouse Button Down を選択してから編集します。

f:id:hiyokosabrey:20190209140223p:plain

 クリック受付するかしないかのフラグをみて分岐させます。

 

これでパネル用Widgetが用意できました。

 

メインになる親のWidgetを用意します。

キャンバスには パネルを並べるための WrapBoxを一つ。

f:id:hiyokosabrey:20190207231937p:plain

中央になるように調整します。

f:id:hiyokosabrey:20190207231820p:plain

f:id:hiyokosabrey:20190207233215p:plain

パネル1枚が 120x120なので、 120x5 + スキマ から指定幅を計算。指定幅を越えたら改行するので、6個目が並ばないように指定します。

Size To Content にチェック付けると、 Size XとSize Y は無意味なので初期値でOK。

 

次に、タイマー用の TextBlockを配置します。

f:id:hiyokosabrey:20190207234327p:plain

とりあえず、WrapBoxのすぐ上あたりに。

次は、クリアしたときの「 Complete! 」をTextBlockで配置。

f:id:hiyokosabrey:20190207234608p:plain

これはクリアしたときまで取っておくので、配置したらVisibilityの設定を非表示(Collapsed)にしておきます。

 

あとは、Click To Start のボタンを配置します。

f:id:hiyokosabrey:20190208002547p:plain

覆うように大きく大胆に広げます。

f:id:hiyokosabrey:20190208002557p:plain

配置したButtonの子供にTextBlockを置くと、中にテキストを置けます。

Hierarchyはこんな感じ。

f:id:hiyokosabrey:20190208003031p:plain

f:id:hiyokosabrey:20190208003505p:plain

 

このままだと後ろが見えないので、Buttonのカラーをカスタマイズします。

とりあえずカラーは 黒 でアルファが 0.5 くらいにします。

Buttonコンポーネントは専用のイベントをいくつか持っているので、Normal、Hovered、Pressed の3か所を触ります。

f:id:hiyokosabrey:20190208004043p:plain

あくまでもボタンの地の色で、テキストブロックのカラーは変化しません。

f:id:hiyokosabrey:20190208220346p:plain

Buttonを大きくするのは、数字のパネルがクリックを受け付けてしまうのを防ぐ目的もあります。

 

キャンバスはこの辺にして、ブループリントを編集します。

 

まずは、数字を配列にセットする関数。

f:id:hiyokosabrey:20190208220655p:plain

配列のIndex番号は 0(ゼロ)始まりだけど、ゲームの表示は 1(イチ)からなので、ForLoopを使って、1~25 の数字を格納。

 

配列をシャッフルする関数。

f:id:hiyokosabrey:20190208220917p:plain

配列にShuffleノードをつなぐだけで配列の中身をシャッフルしてくれます。

 

上の2つの関数を Event Pre Construct につないでおきます。

f:id:hiyokosabrey:20190208223307p:plain

クリックしたパネルの数字が順番通りかどうかチェックするための変数もここで初期値をセットしておきます。

このイベントは 、ブループリントをコンパイルした時点で一度処理されるという特殊仕様です。結構便利な使い方ができるので後ほどご紹介します。

 

次は数字パネルのWidgetを並べる処理。

f:id:hiyokosabrey:20190208225251p:plain

真ん中付近の配列の作り方は、

f:id:hiyokosabrey:20190208225442p:plain

Create Widget ノードの ReturnValue ピンから Promote to Variable(変数へ昇格) して、一旦 "専用の"の変数を作成します。

f:id:hiyokosabrey:20190208225734p:plain

f:id:hiyokosabrey:20190208230257p:plain

Variablesのリストに追加されているので、Detailsから配列に変更します。

f:id:hiyokosabrey:20190208230311p:plain

この操作は、一旦グラフから取り除いてからやると、エラーチェックが走らないのでオススメ。つながった状態でやると警告されます。

 

で、数字パネルをWrapBoxに追加した後は、数字パネルを出現させます。

f:id:hiyokosabrey:20190209034203p:plain

出現開始をする前に、アニメーション終了の通知が欲しいので最後の数字パネルにバインドを施しておきます。そして再び ForLoopを使って一斉に数字パネル全部に数字を渡しつつFADE_INのアニメーションを再生させる関数を呼び出しています。

その関数はこちら。

と、その前にカスタムイベントを準備。

f:id:hiyokosabrey:20190209034855p:plain

数字パネルのバインドで送り返してもらう値がInteger型で2つあります。それを受けるのであらかじめこちらでも2つのInputピンを装備させます。このイベントは後から作っても大丈夫。でも少しだけ手数が増えます。その理由はこれ↓

f:id:hiyokosabrey:20190209170308p:plain

関数の中にカスタムイベントを置くことはできないので、替わりに CreateEventノードをつなぎます。

f:id:hiyokosabrey:20190209170731p:plain

バインドノード経由のイベントをつなぐと、Select Function というプルダウンリストが出てきます。そこでイベントディスパッチャーの値を渡せるイベントを指定するのですが、Inputピンの型と数が一致していないと、プルダウンに出てきてくれないのです。

 

そのカスタムイベントの続きはこんな感じになります。

f:id:hiyokosabrey:20190209172342p:plain

クリックした数字パネルから応答が返ってきた値を比較して、同じなら成功なので、クリックした数字パネルの演出イベントを呼び出します。まだ数字パネルが残っているかどうかチェックして、残っていれば順番をチェックするカウンター用の変数を一つ進めます。

 なんとか 25までクリックできたら、終了処理に移ります。続き。

f:id:hiyokosabrey:20190209174108p:plain

Complete! のテキストを表示して、残ったパネルを消すイベントを呼びます。

 

そろそろ大詰め。ゲーム開始用のイベント。

編集モードをDesignerに変えて、Click To Start 用のButtonパーツを選択。

Detailsタブの一番下に、グラフにイベントを生成するボタンがあるので、On Clicked をクリック。

f:id:hiyokosabrey:20190209180903p:plain

f:id:hiyokosabrey:20190209181039p:plain

ここにゲーム開始の処理をつないでいきます。

f:id:hiyokosabrey:20190209175430p:plain

最後にフラグを True にしていますが、これはタイマー表示に使います。

 

タイマーは  ゼロから始まる~ のでEvent Tick で Float型の変数に加算していきます。

f:id:hiyokosabrey:20190209182303p:plain

ここで便利なノードが、 FormatTextノード。

「単位」をくっつけたり、文章の途中に任意のテキストを挿入するといった使い方ができます。

  詳細は公式サイトにあります→  ユーザーに表示するテキストの書式設定

 こちらのブログエントリーもおすすめです→ UE4ワイルドカードを使った書式設定で文字列を作成する

 

イメージしやすそうな例で説明を書いてみます。

 

取り出した直後はこんな形。

f:id:hiyokosabrey:20190209183359p:plain

ここにピンを増やすのですが、増やし方が変わっています。

例えば、こんな文章があったとします。

 

 おおトンヌラよ、しんでしまうとは ふがいない。

 

この名前のところを、半角の中括弧(波括弧)でピン名を挟んだ形、{ ピン名 }に置き換えます。

 

 おお{CharacterName}よ、しんでしまうとは ふがいない。

 

これを FormatText に入力してみると、こうなります。

f:id:hiyokosabrey:20190209184036p:plain

新たに入力ピンが追加されます。

{ピン名} はいくつでも配置できます。

f:id:hiyokosabrey:20190209184527p:plain

今回は、簡単に Float型の値に、 sec をくっつけています。

{Time}sec

 

これで一通りの用意ができました。

レベルブループリントからViewportに追加して、マウス制御用のノードをつないで、

f:id:hiyokosabrey:20190209185732p:plain

再生してみます。

www.youtube.com

 マウスカーソルがキャプチャできなかったのでちょっとわかりにくいかもですが、一通り遊べてます。

も少し整えないといけないところがあるのですが、そのあたりは次回に回そうと思います。

何度かチャレンジしてみて、なかなか12秒を切れなかった。パネルの大きさとかも影響するかもしれない。数字の色とか、フォントをいじるとまた違った難易度になると思います。一度つくってみるといろいろアレンジしたくなるので楽しいですね。

 

ではでは

ステキなパネルクリックライフを!