みつまめ杏仁

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

そうだ、QUIZゲームを作ろう《おまけ編》クリアへの道 後編

前回タイマーの改造に始まって、ForLoopやらSelectノードやら配列やら説明してたらボリュームがえらいことになったので、2部構成にしました。

 

クイズゲームとして、制限時間内に規定回数分正解するとゲームクリア。という仕様に決めました。前回の記事でその正解数をカウント表示するWidgetを作ったのでいよいよ組み込んでいこうと意気込んだところで、タイムアップの時にタイトル画面に戻るようにしてなかったのを思い出しました。

 

目次

 

 

タイトルへ戻る

タイムアップしてもまたクイズ画面に戻るようになっているので、タイトル画面に移行するように変えます。

ゲーム本体の wb_QuizGame を編集します。

f:id:hiyokosabrey:20210620005150p:plain

 

NEXTボタンを押したときの処理はこうなってました。

f:id:hiyokosabrey:20210620002349p:plain


タイムアップの時だけ、専用のカスタムイベントを用意してやります。

f:id:hiyokosabrey:20210620002917p:plain

これでOK。コンパイルして確認してみる。

 

・・・

 

タイトル画面にちゃんと戻ることができているけど、リトライするとタイマーがリセットできていないことが判明。もう少し詳しく調べるために変数を確認することにします。

タイマーを管理しているのは wb_Main です。

f:id:hiyokosabrey:20210620104633p:plain

効率よくチェックしたいので、タイマーの長さを短くするために 変数 Seconds の初期値を 5.0 にして再生してみると。

f:id:hiyokosabrey:20210620104818p:plain

 タイトル画面で一度出たきりでした。

何度かプレイしてみて判ったことが 2つ。

  1. 残り時間を保持する変数 RemainTime はリセットされる機会がない
  2. WidgetSwitcher に登録したWidgetは、表示されていなくても(アクティブになてっていなくても)EventConstruct は実行される

変数がどこでどう使われているかの確認は、Find References を使います。

f:id:hiyokosabrey:20210620110131p:plain

Variablesリストの変数の上から右クリックメニューで選択できます。

 

エディタ下に Find Results というタブがあって、そこに検索結果が表示されます。

f:id:hiyokosabrey:20210620215138p:plain

このリスト上でダブルクリックすると、配置されている箇所にワープします。

変数で 検索すると、 Get と Set が変数名の前に付きます。

これは、ジャンプするとわかるのですが、値の 入力 と 取得 を表しています。

 

タイムをリセットするには、Seconds の値と同じにする必要があります。Set ~ のところを見てみると、Event Construction のところと、 ポーズをかけたときに関数内の2か所で、 Event Construct はプレイ開始時 1回だけしか通ってませんでした。

なので、回答ボタンを押してポーズしたら、RemainTime は値が変更されます。そしてそのままタイムアップになってリトライしても、変更されたままになっていました。

 

ということで、初期化用のイベントを作って、別の場所からも呼べるようにします。

カスタムイベントを追加して、 initialize と命名。そこへ Event Construct でつないでいたのを移植します。

f:id:hiyokosabrey:20210620223011p:plain

Seconds もこの際なので、 Set の形で置きなおして値を設定しやすくしました。

f:id:hiyokosabrey:20210620222406p:plain

Event Construct には カスタムイベントをつなげば元の通りに動きます。

コンパイルして保存します。

 

 

再び、クイズゲーム本体にに戻ってきました。

この初期化のイベントを、ここに挟めば完了。

f:id:hiyokosabrey:20210620223708p:plain

 コンパイルして問題なければ、保存します。

タイマー問題はこれで解決です。

 

 

組み込む

ようやくカウント表示を組み込んでいきます。

 

組み込む場所は 2か所。

  1. クイズの回答する画面 ← 現在の状況を確認したい 演出は不要
  2. 正解したときの画面 ← 獲得したことを演出付きで見せたい

 

この 2つ タイミングを合わせる必要がありそうです。

流れとしては、

回答ボタンを押した瞬間、正解画面に切り替わります。

f:id:hiyokosabrey:20210621223300p:plain

演出をじっくり見せるには、時間制限のある回答画面では嫌われるので、正解演出画面で見せるのがベスト。

NEXTボタンを押して画面が切り替わると、すぐに次のクイズが始まるので、その時点でカウント表示は更新されていてほしい。

f:id:hiyokosabrey:20210621223557p:plain

流れはこれで行こうと思います。

 

時間制限については、メインの wb_Main でのみ表示されるパーツだったので、wb_Main で管理していました。今回は複数画面に配置しているので、カウント数の管理はもう一段上の wb_QuizGame でやるほうがよさそうです。

 

ということで組み込みを進めます。

まずはクイズのメイン画面から。

f:id:hiyokosabrey:20210619231108p:plain

 

キャンバスに、wb_Count をドロップして配置します。

f:id:hiyokosabrey:20210620000057p:plain

いい感じの場所に配置したら、編集モードをGraphにします。

 

カスタムイベントを新しく追加。

配置したばかりのカウントWidget の関数を呼び出すだけの簡単なお仕事。

f:id:hiyokosabrey:20210621221809p:plain

 このイベントは外から呼び出されるようにしています。いわば中継ってやつです。

 

これで、wb_Main の編集は完了です。

コンパイルして問題がなければ保存します。

 

つぎは、正解演出画面。

f:id:hiyokosabrey:20210621231702p:plain

目立つ位置に置きました。

f:id:hiyokosabrey:20210621232321p:plain

ここで提案。

演出表示が増えてきました。

緊張感のある回答画面から遷移してきて、時間も止まっているので一息つける画面でもあります。

NEXTボタンの表示タイミングに間を開けるのが気遣いというものです。※諸説あり

デフォルト状態として Visibility を Hidden にしておきます。

f:id:hiyokosabrey:20210621234655p:plain

 

キャンバスはここまで。

編集モードを Graph に切り替えます。

 

こうなっています。

f:id:hiyokosabrey:20210622003002p:plain

ここに、カウントのエフェクト再生とNEXTボタンの表示にタイムラグをつくるDelayノードをつなぎます。

f:id:hiyokosabrey:20210622005405p:plain

PlayAnimation ノード と wb_Count の NewGetWithEffect イベントを呼び出したあと、Delay ノードで、少し待ってから、 NEXTボタンの Visibility を Visible に変えます。

NEXTボタンを押したときのイベント OnClicked で、再び NEXTボタンの Visibility を Hidden に戻しておきます。

 

Delayノードは、流れに一呼吸おいたりしてリズムを作ることができるので、演出を重視したい時には大変重宝しますが、使用には注意が必要です。

f:id:hiyokosabrey:20210622222027p:plain

  • 後ろの処理は待たされます(処理にポーズがかかるイメージ)
  • 関数の中では使用できません(右上の時計アイコンが目印)

 

一定時間後に○○ という場合は、Set Timer by Event や Set Timer by Function との違いを理解して使いこなせるとカッコいいと思います。

 

 

NewGetWithEffect イベントには パラメータを受け取るようになっているので、どこかからパラメータ用の値を持ってこないといけません。

f:id:hiyokosabrey:20210622222814p:plain

先頭のイベント StartAnim はBPインターフェイスで作ったものです。

クリックしても Detailsタブは空欄です。

f:id:hiyokosabrey:20210622010417p:plain

 

 

ここでBPインターフェイスを再び編集します。

f:id:hiyokosabrey:20210622010851p:plain

エディタを開いたら、Inputs のところから +ボタンを押して Integer型を選択します。

f:id:hiyokosabrey:20210622011232p:plain

コンパイルして保存したら閉じます。

再び、wb_Right に戻ってみると、

f:id:hiyokosabrey:20210622011614p:plain

ピンが追加されています。

このピンと、カウントWidgetのイベントをつなぎます。

f:id:hiyokosabrey:20210622011834p:plain

まっすぐつなぐとノードと重なるので、リルートノードを使っています。

 

最後に繰り返し遊ぶときのために、カウントの初期化イベントを用意します。

f:id:hiyokosabrey:20210623010944p:plain

 

この正解演出用のWidgetは これで編集終了です。

コンパイルして保存します。

 

 

つなげる

組み込んだカウントを機能させるために、クイズ本体 wb_QuizGame を編集します。

f:id:hiyokosabrey:20210622012048p:plain

 

まずは 編集モードを Graph にします。

 

カウント数を管理するための、Integer型の変数をひとつ追加します。

 f:id:hiyokosabrey:20210622224422p:plain

 

最初にカウントアップしたいのは正解演出画面なので、

正解演出画面に移行するタイミングで カウントをプラスします。

f:id:hiyokosabrey:20210622224846p:plain

正解ボタンを押したときだけ、Count変数に +1 します。

そして、そのプラスされた値を、StartAnim 関数に渡してやります。

f:id:hiyokosabrey:20210622231003p:plain

足し算するための ノードは、 int + int で探します。

f:id:hiyokosabrey:20210622231216p:plain

 

次に正解演出画面から帰ってきたときの処理。

ここでようやくメイン画面 wb_Main のカウントを増やしてやります。

 

メイン画面に切り替えるのは、正解演出画面と、誤答演出画面からの帰り道。

同じところに戻ってくるので、ここを切り分けます。

f:id:hiyokosabrey:20210622232450p:plain

 

正解画面専用のカスタムイベントを追加します。

f:id:hiyokosabrey:20210622232729p:plain

ちょっと狭くなってきたので、少しスペースを作りました。

このイベントでやることは、カウントが規定数に達したかどうかを判定することです。

f:id:hiyokosabrey:20210622233153p:plain

≦ (小なりイコール)で判定します。 ノード検索は半角で <=  と入力します。

f:id:hiyokosabrey:20210622233417p:plain

これで 3 以下 か 3 と同じなら True 、それ以外なら False という判定結果になります。

 

入力ピンが縦に並ぶので直感的じゃないですが、こうなってます。

f:id:hiyokosabrey:20210622234323p:plain

 

判定結果が True ということは、まだノルマは達成していないので、

f:id:hiyokosabrey:20210622235125p:plain

ここで、メイン画面のカウントを更新します。そのまま元の流れに戻します。

 

判定結果が False の場合。つまりは Count に 4 という値が入っているときです。

正解演出画面にいく直前に Count は +1 するので、3の状態で正解すると、まず 4 になってカウントアップ演出を見せてから戻ってきます。

ここで メイン画面に行くのではなく、ゲームクリア画面に行けばいいわけです。

 

いったんこの状態でコンパイルして確認してみましょう。

まだ設問が一つでさみしいですが、想定通りになっているでしょうか?

 

 

Congratulations!

クリアおめでとう画面を作ります。

 

構造的に変わったことをしないのと、タイトル画面に戻るボタンを置くので、 wb_Title を複製して改造することにしました。

f:id:hiyokosabrey:20210623001916p:plain

名前は wb_Clear にしました。

f:id:hiyokosabrey:20210623000327p:plain

やっぱり紙吹雪とか散らしたくなりますね。

いい感じの画像でも配置してみてください。

 

ここはオマケのオマケでテクスチャを使わないマテリアルを使ったキラリをご紹介。

マテリアルエディタの操作の説明は省くので要望があれば別の記事で説明します。

コンテンツブラウザで、Materialを作ったら、下のようにノードをつなぎます。

f:id:hiyokosabrey:20210623002456p:plain

右端のノードを選択した状態で、 Detailsタブから

Material Domain を User Interface

Blend Mode を Transparent

にすると、Widgetで使用できるようになります。

 

コンパイルして保存したら、コンテンツブラウザから、直接Widgetのキャンバスにドラッグ&ドロップできます。

f:id:hiyokosabrey:20210623003021p:plain

 

ブループリントは特に何もしないので、クリア画面はこれで完成です。

コンパイルして保存します。

 

画面を新しく作ったら、WidgetSwitcher に追加しないといけません。

ゲーム本体の wb_QuizGame を編集します。

f:id:hiyokosabrey:20210622012048p:plain

 

編集モードを Designer にします。

 

f:id:hiyokosabrey:20210623003601p:plain

WidgetSwitcher の上にドロップすると、一番下に追加されます。

 

いーなむの編集をします。

f:id:hiyokosabrey:20210623004059p:plain

Newボタンを押してクリア用のいーなむを追加します。

f:id:hiyokosabrey:20210623004203p:plain

保存したら閉じます。

 

ゲーム本体の wb_QuizGame に戻ります。

 

Branchノードの False に画面切り替えする関数をつなぎます。

NewScreenState に クリア画面のいーなむが追加されているので選択します。

f:id:hiyokosabrey:20210623004454p:plain

 

つぎに、クリアおめでとう画面からの戻り先を用意します。

今回はタイムアップと同じにします。

f:id:hiyokosabrey:20210623011648p:plain

 

あと少し

クリアしてもしなくても、タイトル画面に戻るようにしているので、繰り返し遊ぶことができます。

カウントをリセットしないと続きからカウントしてしまうので、カウントの初期化処理を入れます。場所はこのタイトル画面へ切り替えるところ。

f:id:hiyokosabrey:20210623012839p:plain

変数を 0 に戻すのと、正解演出画面の表示を 0 個に戻します。

 

今回はこれで完成です。

このグラフの全貌です。

f:id:hiyokosabrey:20210623013600p:plain

コンパイルして保存したら確認してみましょう。

 

youtu.be

  

今回はここまでです。

 わからないところやツッコミなどあれば、このブログのコメント機能をご利用いただくか、Twitter@MMAn_nin)にてメッセージを送ってください。

 

それなりにゲームぽくできたので、次回でおまけ編を最終回にしようと思います。

クイズゲームらしく設問を増やしてランダムに出題できるようにします。

 

ではでは

ステキなクリア画面ライフを!

 

 

 

 

そうだ、QUIZゲームを作ろう《おまけ編》クリアへの道 前編

引き続きクイズゲームを作っていきます。

 

ここでいったん過去記事リンク

『そうだ、UE4でQUIZゲームを作ろう』

  1. 《準備編》
  2. 《組み立て編》
  3. 《おまけ編》いーなむで切り替えをわかりやすく
  4. 《おまけ編》ボタンのデザインをどうにかする
  5. 《おまけ編》時間制限をつける

 

 1、2まではUMGのチュートリアル記事として書いてみたので、ある程度の基本的なオペレーションに慣れるのと、複数のWidget間のやり取りをゴールとしています。

3以降はおまけ編としていますが、実践的で使えそう(だといいな)なテクニックを紹介しつつそこそこクイズゲームらしく仕上げたいという思いで書いています。自転車の補助輪として見ていただけるといいのかなと。

 

目次

 

 

 

クリアの条件

 タイマーを実装して緊張感を演出できるようになったところで、今回はゲームクリアを実装することにします。

始まりと終わりがあって、そこに成功と失敗が加われば最低限ゲームとしての体をなすことができます。

 

ゲームクリアには条件があったほうが達成感が得られて、嬉しくなりますよね。

そこでクリア条件を考えました。

 

 クリア条件: 制限時間内に設定された正解数を達成すること

 

となると、失敗の条件はおのずと、タイムアップのみ。

 

 

タイマーのしくみを変える

というわけで、さっそく タイマーを改造するところから。

f:id:hiyokosabrey:20210612212145p:plain

前回までのつくりでは、回答して戻ってくるたびに、タイマーがリセットされます。

それを、

回答ボタン押すタイマーストップMain画面に戻ってくるタイマー再開

という流れに改造します。

 

タイマーを再生するのは、Play Animationノード。

そこに Start at Time というパラメータが用意されています。

f:id:hiyokosabrey:20210612222350p:plain
ここが 0.0 だと、頭から再生します。再生終了は 1.0 です。

ということは、ここにストップした時の時間=進捗率 を値にして入力すればよさそうです。

 

UMG では アニメーションをポーズした際に、どこで止まったかを知ることができるようになっています。

f:id:hiyokosabrey:20210612222306p:plain

Pause Animationノードの ReturnValue  を変数に取り置きしておいて、次回 Play Animation ノードに来たときに、Start at Time として渡すだけで再開できます。

 

ですが、今回はこの方法は使いません。0に戻す処理が必要だし、今後 wb_Main の部分的な表示パーツ になる予定なので、メンテナンスしやすいように、wb_Main から受け取る構造にします。

というわけで、Start at Time のピンをカスタムイベントとつなぎます。

f:id:hiyokosabrey:20210612222116g:plain

これでタイマーは改造終了です。

ラインのクロスを解消するのは、カスタムイベントを選択状態にして、Detailsタブから行います。

f:id:hiyokosabrey:20210612222854p:plain

コンパイルして問題なければ、保存して閉じてOK。

 

 

タイマーの制御

となると、タイマーのカスタムイベントに異変発生!ということで、きっと大騒ぎのはず・・・

wb_Main を開こうとすると、

f:id:hiyokosabrey:20210612223930p:plain

アセットのアイコンに未保存のマークがついています。

参照される側が更新されたので、参照してる側としてはコンパイルし直してね、という意味です。

開いてみるとピンが増えてるのが確認できます。

f:id:hiyokosabrey:20210620142516p:plain

 ※《おまけ編》 時間制限をつける の最後のほうで変数管理にした状態で説明します。

 

ここで、残り時間を保持するための変数を一つ追加します。

変数の増やし方は

Variablesリストの右上にある +ボタンを押します。

f:id:hiyokosabrey:20210613000508p:plain

名前は RemainTime

タイプは Float を選択

f:id:hiyokosabrey:20210613000708p:plain

残り時間をゲットして、この変数にセットすることになるのですが、場所は回答ボタンを押した直後。

f:id:hiyokosabrey:20210620142805p:plain

まずVariablesリストからグラフにドロップして取り出しますが、Set~ を選択します。

f:id:hiyokosabrey:20210613001559p:plain

f:id:hiyokosabrey:20210613001849p:plain

Alt キーを押しながらドロップすると、選択の手間がスキップできてラクチンです。

ちなみに Ctrl キーを押しながらだと、 Getタイプでノード化できます。

 

次に、白い4本のラインをつなぎ替えるのですが、スマートにやりましょう。

五角形の白いピンの上で、Ctrlキーを押しながらドラッグを開始すると、複数のラインがまとめて動かせます。

f:id:hiyokosabrey:20210613002634g:plain

 

セットしたタイマーをリセットする Clear~ノードを後ろにつないで挿入完了。

f:id:hiyokosabrey:20210613103200p:plain

実は タイマーハンドラーから、残り時間を取り出せるのですが、クリアしてしまうと 0 になってしまうために、クリアする直前でGetする必要があるのです。

 

Get Timer Rimaining Time by Handle ノードを取り出して変数に入力します。

f:id:hiyokosabrey:20210613104255g:plain

 

ここでアニメーションも止めないといけません。

ノードの配置を整えつつ wb_Timer に用意したイベント StopTimer を呼び出します。

f:id:hiyokosabrey:20210613104956p:plain

中央上部にある青い玉は、リルートノードといって、ラインの流れを意図的に変えることができる便利なノードです。ラインの上でダブルクリックすると間に挿入されるのであとはドラッグしていい感じのポジションに移動させるとつながりが整理できます。

 

これで 残り時間保存タイマーストップアニメーションストップ の流れができました。

 

一見するとスマートにまとまってる気がしますが、タイムアップがゲームオーバーになるという時間にシビアなゲーム性なので、時間を止めるまでの処理は少ないに越したことはありません。クリックした瞬間に止まってほしいと思うはず・・・。

 

 

ブループリントマクロを使う

そこで順番を変えようと思います。画面切り替え通知のイベントディスパッチャーの前にしたいと思います。

f:id:hiyokosabrey:20210620143034p:plain

 といっても、コピペで並べるようなことはしません。マクロを使います。

f:id:hiyokosabrey:20210613122730p:plain

 マウスでドラッグしてマクロにするノードをまとめて選択します。

どれでもいいので、ノードの上で右クリックして、Collapse to Macro を選択。

f:id:hiyokosabrey:20210613123100p:plain

すると

f:id:hiyokosabrey:20210613123753p:plain

ひとつのノードにまとまりました。

ダブルクリックして中身を整えます。

f:id:hiyokosabrey:20210613124001p:plain

右端のOutputノードまでがつながっていないのでつなぎます。

f:id:hiyokosabrey:20210613124251g:plain

これでマクロ編集終了です。

 

元のグラフに戻るには、 マクロのタブを閉じるか、Event Graphのタブにきりかえます。

f:id:hiyokosabrey:20210613124815p:plain

マクロの名前を変えておきます。

エディタ左の Macros リストのところに作ったばかりのマクロが追加されているので、右クリックするか、F12キーでリネームします。

f:id:hiyokosabrey:20210613135055p:plain

pauseTime と命名しました。

次につながったラインを切ります。

右クリックでまとめて切ることができます。

f:id:hiyokosabrey:20210613135701g:plain

このマクロを間に入れます。

f:id:hiyokosabrey:20210620143234p:plain
 

残りの分もグラフにマクロをドロップして同じようにつなぐのですが、ちょっとだけラクをしましょう。

カスタムイベントのピンからドラッグして検索するだけでも、挿入できます。

f:id:hiyokosabrey:20210620145027g:plain
 

こうなりました。

f:id:hiyokosabrey:20210620143500p:plain


マクロは、同じノードのまとまりが、別の場所でも使われるときに便利です。

いくつかのノードがまとまると、ある一つのタスクになります。タスクに名前を付けて管理できるので、何をしているか分かり易くなるし、ブループリントがスッキリします。マクロは関数やイベントと違い、自身以外のアセットから呼び出せません。ローカルな存在です。

 

 

停止から再開へ

あとは再開した時の処理。

その前に、残り時間を保持する変数は、初期値を制限時間と同じにしておかないと、残り時間がゼロでゲームスタートしてしまいます。

Event Construct で 2つの変数 RemainTime と Seconds の値を揃えておきます。

f:id:hiyokosabrey:20210613142717p:plain

これで、Seconds の初期値をいじっても、RemainTime も同じ値にできます。

10秒かな、15秒かな~とかいろいろ試すには、Seconds の値をいじるだけで済みます。

 

改めて再開処理。

これも下の部分を改造していきます。

f:id:hiyokosabrey:20210620143643p:plain


まず Set Timer by Event の Time につながっているのを、 RemainTime に替えます。

f:id:hiyokosabrey:20210620143823p:plain


つぎは Start at Time です。

 

変数 RemainTime には 残りの秒数が値として持っています。wb_Timer では PlayAnimation ノードでアニメーションを管理するのですが、再開するために時間指定ではなく進捗率を指定することになります。進捗率はアニメーションがすべて再生したときに 1.0 になる値です。 ちょっと面倒ですが計算してから渡すことになります。

例えば、制限時間が 10秒で、たまたま 6秒が経過したときに回答ボタンを押した場合。

 

f:id:hiyokosabrey:20210613152658p:plain

残り 4.0秒 という数字を何とかして 進捗率である 0.6 に変えなくてはいけません。

そこでこの計算で進捗率を出します。

 

f:id:hiyokosabrey:20210613154041p:plain

 

ノードにすると、こうなります。

f:id:hiyokosabrey:20210620143926p:plain
 

タイマーの改造はこれで完了です。

これでコンパイルしてテストしてみましょう。

f:id:hiyokosabrey:20210613172946p:plain

f:id:hiyokosabrey:20210613173124p:plain

f:id:hiyokosabrey:20210613173137p:plain

回答ボタンを押して、結果表示から戻ってきた時に、ちゃんと続きからタイマーが動いていればバッチリ。

 

 

 

カウント表示をつくる

タイムアップの流れができたところで、新しく正解数をカウントする表示を作ります。

新しくWidgetブループリントを用意します

f:id:hiyokosabrey:20210612101123p:plain

アセット名は wb_Count としました。

 

『ノルマ』にしようかと英語のスペルを調べてみると、普段よく使ってる割にあまりいい歴史背景の言葉じゃなかったのでしばらく彷徨った結果『カウント』にしました。いろいろ使いまわしの利く単語でもあるということで。

 

見た目には『数字』と『ゲージ(アイコンタイプ)』のどちらにしようか考えてみます。

f:id:hiyokosabrey:20210612102804p:plain

 

制限時間があるし、どうしてもクイズゲームは文章を読む時間が多くなります。少しでも脳に情報処理負荷をかけないほうが喜ばれると思うので、『ゲージ』 を採用します。

『数字』 は分母がどれだけ増えてもコンパクトで場所を取らないのがメリットですが、数字の表記から「あとどれくらい」を判断する必要があるので、直感的な把握には向いていません。ゲームのテンポにゆとりがあったり、判断できる時間のあるゲーム画面で採用できます。

一方の 『ゲージ』 は全体の長さ(量)がネックになります。

あまり多くなるようだと、アイコンではなく棒ゲージにしたほうが良さそうですが、クイズゲームでそれほど多くならない想定。長くなるとしたら、おそらくラスボス戦。その場合だけノルマ制を廃止して、ボスに体力ゲージを設定、それを削った方が特別感が出て盛り上がると思います。時間いっぱいになると大技喰らってGAME OVER。

そういった、シチュエーションの変化で、UIの構成が変わることは日常茶飯事なので、いろんなアイデアを持っておくといいことありますよ。

 

アイコンタイプのゲージを採用するということで画像を2つ用意しました。

「あるとき」左と「ないとき」右。

f:id:hiyokosabrey:20210612112020p:plain

f:id:hiyokosabrey:20210612114806p:plaintex_circle_0.png

f:id:hiyokosabrey:20210612114901p:plaintex_circle_1.png

 

ブログの下敷きと同じ白なので見えないけどいます。

右クリックで保存してお使いください。

 

画像を2つUE4にインポートしたら、キャンバスに配置します。

ノルマの数を可変させたい場合は HorizontalBox を使ってレイアウトすると可能ですが、説明が長くなりそうなので今回は固定の数で進めます。

Image を4つ等間隔に並べて、「ないとき」のテクスチャをセットします。

f:id:hiyokosabrey:20210612115418p:plain

テクスチャが 64x64px スキマは 16pxなので、80px ずつ並んでいます。

 

「COUNT」 は Text、下線 は Image で作りました。この2つは装飾です。

 

 

カウントアップ演出

ここにエフェクトキャラを追加します。

もう一つ Image を追加します。テクスチャは「あるとき」です。

f:id:hiyokosabrey:20210614000738p:plain

通常は非表示なのと、ブループリントで位置を変更するので、場所はどこでもよいのですが、レイアウトするときに余計なサイズ計算されて配置しにくいので、左上に重ねて置きました。

通常で非表示にするには、DetailsタブにあるBehabior(ビヘイビア)のVisibility(ビジビリティ)を Collapse にしておきます。

f:id:hiyokosabrey:20210614001900p:plain

Collapse はゲームを再生中に存在しないものとして扱われるので、処理負荷軽減になります。一方同じ非表示設定の Hidden は見た目に見えないだけなので、Collapse よりは負荷が高くなります。

このエフェクトはたまにしか出ないうえに、他のパーツのレイアウトに干渉しないので、Collapseを選択しました。

 

そしてアニメーションを付けます。名前は NEWGET としました。

f:id:hiyokosabrey:20210614001335p:plainVisibility と、 Transform の Scale 、 Render Opacity の3つ。

f:id:hiyokosabrey:20210614001737g:plain

 

ヒエラルキーはこうなってます。

f:id:hiyokosabrey:20210614002753p:plain

ちょっと気づきにくいですが、飾りの下線とCOUNTの文字は、Is Variable を無効にしているので、[ ] がつけられています。

 

これでキャンバスでのレイアウト作業は完了です。

 

編集モードをGraph に変えます。

 

 

ふるまいを作る

まず Image配列 にします。

Variablesのリストに並んでいる Image を 4つ グラフにドロップします。

f:id:hiyokosabrey:20210615001708p:plain

順番は左から順番に扱うので配列にする際にタテに並べます。

 

キャンバスにはこう並んでました。

f:id:hiyokosabrey:20210615000147p:plain

 

前もって、 変数タイプがImage の配列変数を作ってもOKですが、変数の型がよくわからないうちは、逆引きみたいな作り方がオススメ。

f:id:hiyokosabrey:20210615000301g:plain

名前を変更して Event Pre Construct につなぎます。
Images と命名

f:id:hiyokosabrey:20210615001613p:plain


配列  というのは、同じタイプの Variable(変数)がたくさん存在していて、いちいち名前を付けて管理するのが面倒なときに、配列という形態にします。上のMake Array ノードのピンに書かれているように [0] [1] [2] [3]  と番号をつけて管理するのです。この番号のことを Index番号とか 添字(そえじ)と呼びます。

身近な例で、コインロッカー がイメージしやすいと思います。

コインロッカーは入りさえすればなんでも入れられますが、配列変数の場合は、型(タイプ)が1種類固定なので、どちらかといえば下駄箱のほうがイメージが近いかも。

 

 

ここで関数を用意します。

この関数は指定したカウント分の画像を「ないとき」から「あるとき」に切り替えます。

エディタ左の My Blueprintタブにある Functionsリスト の +Function ボタンをクリックします。

f:id:hiyokosabrey:20210615235406p:plain

名前は SetCount にしました。
で、最終的にこうなります。

f:id:hiyokosabrey:20210615235618p:plain

 

順番にいきますね。

まずは For Loop ノード。とてもメジャーなのでよく出会います。

f:id:hiyokosabrey:20210615235831p:plain

指定した回数だけ繰り返すノードです。

 

ループについて

ノード右にある  Loop Body から先の処理 をぶん回します。

回数分回すと  Complete に移ります。

ループ処理が終わった後の処理は、 Complete 以降につないでいきます。

Loop Body の先には、できるかぎり単純で軽くてレスポンスのいい仕事をさせるようにします。

特にアニメーションやDelayなど時間を扱うような処理はForLoopには向いていません。コンパイルは通るけど、玉突きが起こって引きつったり警告がでたりします。

回す回数は、 First IndexLast Index という2つのパラメータで指示します。

First Index がループ開始の番号。

陸上のトラックをIndex番号がゼッケンに書かれたランナーがリレーで走るところをイメージしてみてください。

First Index が0 つまり最初のランナーのゼッケン が 0番ということです。

0番のランナーが無事走り終えると、ゴールに待ち構えていた Last Index と比較します。0番とは違うので、次は ゼッケン1番のランナーが走ります。帰ってきたら、またLast Index と比較。違うので次2番。という風に順番にカウントを増やしながら次々走っていきます。

ある時 Last Index と同じ ゼッケン番号のランナーが帰ってきました。そのタイミングでようやく For Loop は仕事を終えることができます。

 

今回は ノルマの表示が  4つ なので、計 4回 まわします。

なので、 First Index は 0(初期値) Last Index は 3 になります。

  

    f:id:hiyokosabrey:20210616003653p:plain

 

First Index は 0以外の値ももちろんOKです。

First Index を 1 にすると、Last Index はまんま 回数と同じ値になります。

なぜ 0 始まりなのか?それは 配列の Index が 0 始まりで、ForLoopと相性がいいからです。他にも 0始まりが便利な場面がたくさんあります。

 

 

次は、配列の中身を取り出す Get ノード。

配列は Index番号を指定するので、専用の Get ノードが用意されています。

まず Variablesリスト にある Images を グラフにドロップします。 Get タイプで。

f:id:hiyokosabrey:20210616005413g:plain

For Loopノード右(出力側)にある Index ピンとつなぎます。

f:id:hiyokosabrey:20210616004958p:plain

これで配列の中身 Index 0~3 を順番に取り出すことができます。

 

取り出したものをどうするか?

画像を差し替えるためのノード、 Set Brush from Texture ノードをつなぎます。

f:id:hiyokosabrey:20210616010014p:plain

Image に直接テクスチャを渡してくれるノードです。

次にこの左にある Texture ピンからドラッグして Select ノードを取り出します。

f:id:hiyokosabrey:20210616234550p:plain

Select ノードはつなぐ対象によって見た目が変化します。慣れないうちはつないでいいのか戸惑うと思うので、不安を感じる場合、この方法だとひと手間減るのでオススメです。

f:id:hiyokosabrey:20210616235059p:plain

Option ~ のピンのところに テクスチャを セットします。

セットする方法は 3つあります。

  1. Select Asset のプルダウンから探す
  2. コンテンツブラウザで選んでおいてから白い矢印ボタンをクリック
  3. コンテンツブラウザからドラッグして直接ドロップ

 

f:id:hiyokosabrey:20210617000115p:plain

Selectノードは条件によってReturnValue から出されるデータを変えることができます。

その条件とは、

指示されたカウント数とForLoop の Index番号と比較した結果です。

というわけで 指示してもらうために、この関数に 値を受け取るための Inputs を一つ追加します。

変数のタイプ(型)は Integer(整数)、名前は Count としました。

f:id:hiyokosabrey:20210617001739p:plain

 

あとは 条件式 をつなげば完成。

f:id:hiyokosabrey:20210617002642g:plain

Count を いきなり マイナス 1 しているのは、個数を 配列に合わせるためです。

f:id:hiyokosabrey:20210615232803p:plain

 

<= は 「小なりイコール」です。日本では「 ≦ 」で習いますね。プログラミングでは使わないのでキータイプする際は半角の < と = を並べて書きます。

 

条件の評価について

どうなっているかというと、例えば カウントが 2個 の時。

今回 ForLoopでは 4回 処理します。毎回 Index番号と比較するのです。

 

f:id:hiyokosabrey:20210617010121p:plain

 

実は Selectノードと小なりイコールのノードをつないだ瞬間、Selectノードは変化していたのです。

f:id:hiyokosabrey:20210617010740p:plain

 

ちなみに0個の指示が来たときはこうなります。

f:id:hiyokosabrey:20210617011355p:plain

4個だと すべて True になります。

Selectノードは判定結果にもとづいて渡す内容を振り分けてくれるので結構便利なヤツなのです。

 

これでこの関数は完成です。

この関数さえあれば、必要な機能は揃ったことにしてもいいのですが、あとひとつ

アニメーションの再生が残っていました。

 

 

イベント グラフに戻ります。

 

呼び出されたときのために

Integer(整数)型の変数を一つ用意します。

f:id:hiyokosabrey:20210615232107p:plain

名前をCount にしました。

この変数は、表示してほしい数を受け取って保持するために使います。

 

新しくカスタムイベントを用意してそこにつなぎます。

カスタムイベントは NewGetWithEffectと命名

f:id:hiyokosabrey:20210617230337p:plain

 

そろそろ基本的な操作は慣れてきたころだと思うので、少しずつテンポアップします。

 

つぎにやるのは、エフェクトを新しくゲットするカウントのところに置きなおす処理。

f:id:hiyokosabrey:20210617231108p:plain

UMGのキャンバスに配置したものは、Position というパラメータで管理しています。

f:id:hiyokosabrey:20210617231322p:plain

なので、ここを書き換えるときは、Slot as Canvas Slot というノードを間に挟むのが基本になります。

この場合、いきなり Slot as ~ ノードを探すより、

Image Effect をドロップしてから、Slot as ~ をドラッグで取り出して、そこから Set Position です。

 

次に 指定する座標(In Position)が 0, 0 のままだといけないので、キャンバスに並べたImage から取得します。

Set Position ノードがあるということは 、Get Position もあるということになります。

f:id:hiyokosabrey:20210617232208p:plain

 ここでもマイナス1して配列から取り出します。

f:id:hiyokosabrey:20210615232803p:plain

実は0個の指定でこのイベントが呼ばれると、Index に -1 という番号は存在しないので、エラーになります。

f:id:hiyokosabrey:20210617234005p:plain

4個までしか置いていないので、当然 5以上の指定でも Index番号[4]以降が存在しないのでエラーになります。

そもそも新しく追加するのに 0個の指定はおかしいし、その場合指定する側が修正すれればいいのです。5個以上については、今後の拡張性を決めてからでも問題ないでしょう。今回はひとまず4個獲得したらゲームクリアにするので、5以上の値がくることもないはずです。そのクリアの判定はこのWidgetで行うことでもありません。

 

ちなみに

先の関数で -1 を許容していたのは、Index番号として使用しないからです。ForLoopから出てきたIndex値は 0~3 で、配列の範囲を越えることがないためエラーはでません。

 

ここまでで、指定した個数のところにエフェクトを置くことができました。

ようやくPlay Animation です。

f:id:hiyokosabrey:20210618002315p:plain

Get End Time ノードは アニメーションの終了時間を教えてくれるノードです。

なので、 Set Timer by Event に渡すと、アニメーションの再生が終わったタイミングで任意のイベントを呼び出すことができます。

Play Animationノードは再生を開始するだけして処理は次のノードに移ります。

ほぼタイムラグを意識することなくタイマーを発動させることができます。

UIではアニメーションが終わったら○○して、それが終わったら今度は◇◇で、という風に演出の終わりを待つことがよくあります。上記のはそういう場合の対策のうちの一つです。個人的にメンテナンスがしやすいと思うのでよく使います。

 

あと少し

Set Timer by Event にカスタムイベントをつないでいきます。

仕上げはこのようになります。

f:id:hiyokosabrey:20210618005848p:plain

 演出のアニメーションが終了しているので次回のために、エフェクトは非表示(Collapse)にします。タイムラインでVisibility を 表示(Visible)にしているので、流れ的にちゃんと交互になります。

初期状態: Collapse

この 表示・非表示のタイミング制御が結構表示系バグのなかでも特にメジャーなやつという印象があります。Visibility の状態は タイムラインでしかやらない、ブループリントだけで制御する、という縛りを作ったほうがいい場合もあります。

最後に、先に用意しておいた関数 SetCount をつなぎます。

 

これで準備完了。

説明が長くなりましたが、イベントグラフの全貌はこれだけです。

f:id:hiyokosabrey:20210619112310p:plain

 Event Construct と Event Tick は使いません。

 

この wb_Count の仕様をまとめると、

  • 表示したい個数を指示された → SetCount 関数を呼び出してもらう
  • カウントアップしたい → NewGetWithEffect イベントを呼び出してもらう
  • 個数は 0~4 で指定してもらう

 

コンパイルして保存したら閉じて大丈夫。

 

あとはこのカウントを表示したい場所に仕込むだけですが、さすがに長くなったので、前後編に分けることにしました。

今回はこの辺までにします。

 

次回 クリアへの道 後編 で組み込んでいきます。

そんなに間があかないように頑張りますので、お付き合いくださる方はもうしばしお待ちいただけると嬉しいです。

 

記事内容について、わからないところや、ツッコミ等あれば当ブログのコメント機能か、Twitterの方からメッセージいただけると対応します。お気軽にどうぞ~

 

ではでは

ステキなカウンター表示ライフを!

 

 

 

 

 

 

 

 

 

 

 

 

そうだ、UE4でQUIZゲームを作ろう《おまけ編》時間制限をつける

 クイズゲームには時間制限は当たり前ということで、作ってみたいと思います。

表現方法によっていろんな作り方があるので、どういう形にしようか迷ってしまいました。

 ただ一口にタイマーといっても、目立ち具合というか、主張する強度みたいなのがあって、レースゲームみたいなタイムアタック系のゲームと脱出劇や爆弾解除みたいな時限系のシチュエーションとは与える印象は変えた方がいいですよね。この辺またどこかで記事が書けたら書こうと思います。

 

 チュートリアルって最適解なものを無駄なく教える場というのが求められているんだろうなとは感じつつ、ゲームUIのように解がたくさんあるとチョイスがむずかしいのですよ、と一応言い訳を。

 

 シンプルにUMG使ったやつと、マテリアルを使ったやつ、どちらにしようかちょいとばかし悩んで、UMGだけで作るのを紹介しようと思います。

 見た目はゲージタイプですが、プログレスバーは使用しません。アニメーションを使いつつ、あとから調整できるタイマーにします。

 

仕様としては、

  • 一定の秒数をゲージで表現
  • 時間の長さを調整可能
  • 徐々に短くなることで焦らせる
  • 0になるとタイムオーバー

 まだノルマの仕様が入ってませんが、タイマーができたら実装してもいいかな。いずれ問題もたくさん仕込んでランダムチョイスもやりたいので、今のうちから問題を集めておくとしましょう。

 

 目次

 

 

専用のWidget

新しくタイマー用のWidgetブループリントを用意します。

f:id:hiyokosabrey:20210605104803p:plain

wb_Timer と命名

 

さっそくキャンバスに Image2つ 配置します。

f:id:hiyokosabrey:20210605110650p:plain

ひとつは下敷き、ひとつは伸び縮みするゲージ本体です。

それぞれ、 Image_Gauge、 Image_base と命名

 

いい感じにカラーをつけて重ねます。

下図は Text を配置していますが飾りなのでお好みでアレンジしてみてください。

f:id:hiyokosabrey:20210605110940p:plain

f:id:hiyokosabrey:20210605110953p:plain

 

テキストの代わりに画像が用意できるなら、ストップウォッチのアイコンとかが合いそうです。

ゲージ本体と下敷きの重ね方次第で立体的に見せることもできます。

f:id:hiyokosabrey:20210605112737p:plain

 

 

キャンバスにはこのようにレイアウトしました。

f:id:hiyokosabrey:20210605113127p:plain

参考までに、

ゲージ本体の長さ(Size X)は 1200  、高さ(Size Y)は 8

ゲージ下敷きの長さは 1200  、高さは 16

 

一度ここでコンパイルして保存します。

 

クイズのメイン画面担当のWidgetに配置してみましょう。

f:id:hiyokosabrey:20210605114427p:plain

 

編集モードをDesignerにして、新しく作った wb_Timer を 探してドロップします。

f:id:hiyokosabrey:20210605114817p:plain

サイズ感や色味を確認して気になるようだったら戻って調整します。

 

OKなら、そのままコンパイルして保存して、wb_Timer に戻ります。

f:id:hiyokosabrey:20210605161039p:plain

 

 

ゲージが減るアニメーション

ゲージ本体の Image に 長さを変えるアニメーションを付けます。

 

ゲージの長さを変えるには、Detailsタブの下のほうにある、Render Transform の Scale X を変化させます。

f:id:hiyokosabrey:20210605161849p:plain


ただ、初期状態で Pivot X の 値が 0.5 なので、ゲージの真ん中が中心になっています。

f:id:hiyokosabrey:20210605161601p:plain

 

そこで、Pivot X の値を 0.0 に変えます。

f:id:hiyokosabrey:20210605161905p:plain

Pivot はそのパーツを変形させる基準となる点です。

f:id:hiyokosabrey:20210605162335p:plain

同じくDetailsタブの Slot(Canvas Panel Slot)にある Alignment(アライメント) と同じ認識で問題ないと思います。

 

Alignment はレイアウトのために使用するパラメータで、Pivot は変形のためのパラメータという扱いです。

 

パーツの左上が (0, 0)右下が (1, 1)になるので、初期値の(0.5, 0.5)というのは、ド真ん中になります。

f:id:hiyokosabrey:20210605163152p:plain

 

この状態でScaleのアニメーションを付けます。

水平方向だけなので、 Scale X に 1.0 → 0.0 の変化をつけます。 尺 は 1 秒

f:id:hiyokosabrey:20210605164025p:plain

この ボタンをクリックしてCurveエディタを開くと確認できるのですが

f:id:hiyokosabrey:20210605164750p:plain

UE4は初期状態でEase In-Out が設定されています。

f:id:hiyokosabrey:20210605164639p:plain

f:id:hiyokosabrey:20210606161826g:plain

タイマー表示に緩急は不要なので、リニアに変えます。

このカーブエディタからも操作できますが、普段のTrack編集中でも変更できます。

Keyを打ったポイントを選択して、右クリックメニューから Linear を選びます。

f:id:hiyokosabrey:20210605165423g:plain

Curveエディタの場合は、Keyを打ったポイントを選択して、右上にある、アイコンボタンからリニアにできます。

f:id:hiyokosabrey:20210605173306p:plain

 

f:id:hiyokosabrey:20210606161536g:plain

 

1秒のアニメーションなんて一瞬です。

どんだけ早押しゲーだよ!無理ゲーだよ! という声が聞こえてきそうですが、これにはブループリントで答えることにしましょう。

 

おっと、その前にひとつやることがありました。

ゲージ本体の初期状態を確認します。

アニメーションを選択していない状態で、

f:id:hiyokosabrey:20210606113852p:plain

ゲージ本体の Scale X を 0.0 にします。

f:id:hiyokosabrey:20210606114028p:plain

見た目にサイズが 0 になって消失します。

f:id:hiyokosabrey:20210606114229p:plain

これは、アニメーションを再生しきった状態と同じにしておくためです。

UMGのアニメーションは再生終了すると、自動でデフォルト状態に戻ります。

その時、デフォルト状態が満タンな見た目だと、せっかく減らしたゲージが回復したように見えてしまうのです。

 

では気を取りなおして 編集モードをGraph に切り替えます。

まず、何もないところで右クリックしてカスタムイベントを取り出します。

f:id:hiyokosabrey:20210605181047p:plain

Add Event の中にあります。上の方にあるので検索しなくてもすぐ見つかるはず。

イベント名は、 startTimer と名付けました。

f:id:hiyokosabrey:20210605181303p:plain

このイベントで アニメーションを再生させます。

f:id:hiyokosabrey:20210606150942p:plain

 


ちょっとひと工夫

再生するだけならここまでなんですが、ひと工夫加えます。

 

カスタムイベントにパラメータ(引数)のピンを追加します。

Detailsタブから Inputs で + ボタンを押す以外にグラフ内でドラッグする方法を紹介していおきます。

f:id:hiyokosabrey:20210605182041g:plain

型がわかっていなくても正確にピンが追加できるので、結構便利です。

間に計算ノードを追加するので、つないでから切断してます。

 

ピンの名前を Seconds (秒)に変えます。

f:id:hiyokosabrey:20210605194913p:plain

 

カスタムイベントからは、秒数を受け取る想定。

PlaybackSpeed は 1.0 (初期値)が 通常のスピード。

2.0 で 2倍速。 0.5 で1/2の速度でスロー再生になります。

ということで、割り算のノードを追加します。

 

割り算は / (半角スラッシュ)で検索できます。

f:id:hiyokosabrey:20210605195949g:plain

カスタムイベントのパラメータと、PlaybackSpeed が float型(浮動小数)なので、  float / float を選択する必要があります。

 

秒数をプレイバックスピードに変換するには、 1.0 を秒数で割ります。

f:id:hiyokosabrey:20210605200856p:plain

 

 

f:id:hiyokosabrey:20210606150845p:plain

用意したアニメーションの尺は 1秒。

例えば5秒の再生速度にしたい場合  1÷5 ということになって、 PlaybackSpeed は 0.2 です。

本来のスピードの1/5の速度ということで、5倍の時間をかけるとようやく1秒の長さを再生したことになります。まぁゆっくり再生します。

割り算というのはちょっとイメージしにくいですよね。

 

この仕様にしておくとメリットがあります。

  • あとからタイマーの長さを調整しやすい
  • ゲーム中にアイテム使用やデバフ、ボス戦等、特別な状況で変更が可能
  • アニメーションのトラックを再編集しなくていい
  • タイマーの終了タイミングを管理しやすい

最初から最後まで制限時間が変化しないのであれば、決め打ちでタイムラインにキーを打っても大丈夫ですが、親のWidgetとの連携が少しだけ複雑になるので、今回はシンプルに作ります。

 

あと必要そうなイベントを2つ用意します。

f:id:hiyokosabrey:20210606150829p:plain


readyTimer

アニメーションがスタートしないと満タンにならないので、一時的に満タン状態にするカスタムイベントです。今はクイズの設問をいきなり表示していますが、「第1問」とか演出が増えるかもしれないので、一応用意しておいてもいいかな~という程度です。

 

stopTimer

何かしらのポーズがかかったり、タイムボーナスの計算したりするときに必要になりそう、という程度です。

 

残りをつなぐとこうなります

f:id:hiyokosabrey:20210606150536p:plain
Image_Gauge はキャンバスに配置した ゲージ本体 の Image です。

Scale に 1.0 を入れると、本来のサイズで表示してくれます。

 

アニメーションを停止するのは Pause Animeation ノードです。

Stop Animation ノードが用意されているのですが、こちらは停止したあと、状態をアニメーションする前の初期状態にリセットしてしまうので、今回の場合ゲージが消えてしまうことになります。時間が止まった感を出すためにポーズさせることにしました。

 

ちなみに

イベント名を ”stopTimer” にしているのはノード名とちぐはぐな感じですが、イメージとの距離感で、”stop” という言葉を採用しました。イベント名を ”pauseTimer” にすると再開を期待したりしそうだし、クイズゲームというのもあって、ポーズ状態を見せることもないのが理由だったりします。まぁ後々なるべく誤解が起こりにくいのがいいなぁという程度の考えです。こういうイベントや関数は自身で呼ぶより、他の場所から呼び出して使うことが多いですし。

 

タイマーはこれで完成です。

コンパイルして問題なければ保存します。

 

 

実装

早く減らすところを見てみたいので、wb_Main を編集していきます。

f:id:hiyokosabrey:20210605114427p:plain

 

カスタムイベントを追加します。

f:id:hiyokosabrey:20210606150439p:plain

wb_Timer が持っているカスタムイベント startTimer を呼び出しています。

制限時間は10 秒ということでパラメータに 10 を入力しています。

 

関数ノードやイベントノードを取り出したい場合、先にVariablesリストにいる wb_Timer を Getタイプで取り出して、ドラッグして検索すると見つけやすいです。wb_Timer は、キャンバスに置くと同時に、Variables リストに追加されます。

f:id:hiyokosabrey:20210606153113g:plain

エンジンの言語環境が English の場合は、ざっくりと "call" で検索できて便利です。

 

これでコンパイルして問題なければ保存します。

 

 

次にタイマーをスタートさせるために、ゲーム本体の wb_QuizGame を編集します。

f:id:hiyokosabrey:20210606154401p:plain

 

タイマーをスタートさせるタイミングは 2か所。

f:id:hiyokosabrey:20210620115508p:plain


メイン画面に切り替わるタイミング。

 

まずは 最初のタイトル画面でSTARTボタンを押したとき。

 

以下の画像はこちらの記事を適用しています。

そうだ、UE4でQUIZゲームを作ろう《おまけ編》いーなむで切り替えをわかりやすく - みつまめ杏仁

f:id:hiyokosabrey:20210606155142p:plain

 

もうひとつは、回答ボタンを押して、正解か不正解かの画面から帰ってきたとき。

f:id:hiyokosabrey:20210606155410p:plain

 

ひとまずこれで確認できるはず。

コンパイルして再生してみましょう。

f:id:hiyokosabrey:20210606162157p:plain

 

無事動いたのを確認したら、タイムアップ画面を追加します。

 

 

タイムアップ画面

ちょっとラクするために正解演出画面の wb_Right を複製することにします。

f:id:hiyokosabrey:20210606163415p:plain

 

テキストを 『TIME UP』に変更して、アニメーションもちょっといじってみる。

f:id:hiyokosabrey:20210606165327g:plain

これで編集終了。

コンパイルして保存します。

 

 

これを WidgetSwitcher に追加します。

クイズゲーム本体のWidgetを編集します。

f:id:hiyokosabrey:20210606201148p:plain

 

Paletteタブの UserCreated から wb_TimeUp を探します。

f:id:hiyokosabrey:20210606191555p:plain

f:id:hiyokosabrey:20210606192103p:plain

 

いーなむにも登録します。

f:id:hiyokosabrey:20210526004846p:plain

f:id:hiyokosabrey:20210606192330p:plain


これで切り替える準備完了です。

 

今 切り替えのつながりのフローイメージはこうなりました。

f:id:hiyokosabrey:20210606200132p:plain

 

まだこの状態では切り替わりません。

 

切り替えを行うのは → wb_QuizGame

タイマーをコントロールしているのは → wb_Main

 

ということで、wb_Main がタイムアップとした時に、wb_QuizGame に通知してやる必要があります。すでに wb_Main は 4つの回答ボタンをクリックしたとき wb_QuizGame に通知しています。このイベントディスパッチャーに相乗りできると、新たにイベントディスパッチャーとバインドのセットを新設しなくても済みそうです。時間切れも無回答というひとつの答えですし。

 

切り替えるためには

ということで、今度は wb_Main を編集します。

f:id:hiyokosabrey:20210606201310p:plain

回答ボタン用のイベントディスパッチャーを選択して

f:id:hiyokosabrey:20210620115635p:plain


Detailsタブから、 Inputsのパラメータを追加します。

変数のタイプは Boolean。

f:id:hiyokosabrey:20210606201412p:plain

パラメータ名を TimeUP にしました。

パラメータ名を変更してコンパイルすると、エラーが出てしまいます。

かといって New Paramのままだと後で意味が分からなくなるので、ここでエラーをつぶしておきます。

f:id:hiyokosabrey:20210606201859p:plain

 

f:id:hiyokosabrey:20210620120232p:plain

グラフを見てみると、置いたやつ全部エラーになってますね。

f:id:hiyokosabrey:20210620121710p:plain



よくみると、追加したパラメータの名前が New Param のままです。更新が中途半端に行われた感じに見えます。仕方ないので、ノードをリフレッシュしてやります。

ERROR! になっているノードの上で右クリックして Refresh Nodes を選択。

f:id:hiyokosabrey:20210620122845g:plain


f:id:hiyokosabrey:20210620122031p:plain


これでコンパイルエラーは消えます。

 

あとはタイムアップのタイミングでこのイベントディスパッチャーを Call すればよさそうです。

QuizStartのカスタムイベントのところで、タイマーを開始しているので、ここに仕込むことにします。

 

Set Timer by Event ノードを使います。

f:id:hiyokosabrey:20210607220707p:plain

これは 指定した時間が経つと、カスタムイベント を呼び出してくれるノードです。

カスタムイベント は バインドしたときと同じようにつなぎます。

f:id:hiyokosabrey:20210607221300p:plain

ここにイベントディスパッチャーをつなぎます。

f:id:hiyokosabrey:20210620141904p:plain

TimeUp にチェックをつけておきます。

 

いったんコンパイルして保存したら、

クイズゲーム本体でタイムアップ画面に切り替える処理を作ります。

 

f:id:hiyokosabrey:20210606201148p:plain

 

回答ボタンを受け取るバインド処理のところに変化が!

f:id:hiyokosabrey:20210620141804p:plain

 

ここの ブランチノードの前にタイムアップの分岐を挿入します。

f:id:hiyokosabrey:20210620141657p:plain

タイムアップ優先で判定します。

正解、不正解で使ってる 画面切り替え用の関数を使います。いーなむを登録しているので、TimeUpを選ぶだけ。簡単!

カスタムイベントの赤いラインのクロスが気になる場合は wb_Main のイベントディスパッチャーの方で順番を変えてやると解消できます。

f:id:hiyokosabrey:20210607224130p:plain

コンパイルして保存すると反映されます。

f:id:hiyokosabrey:20210607224300p:plain

ここで再生して確認してみましょうか。

 

f:id:hiyokosabrey:20210607233944p:plain

無事切り替わりました。

 

かんせー! と叫びたいところですが、バグを発見。

普通に時間切れだと問題ないのですが、回答してNextボタンを押さずに放置していると、きっちり時間が来てタイムアップ画面に切り替わります。

真面目過ぎ!と突っ込みたくなりますが、タイマーを使っているのが原因なので対策を講じます。

 

 

 

f:id:hiyokosabrey:20210606201310p:plain

 

Set Timer by Event ノードにある Return Value ピンからドラッグして、変数を作ります。Promote to Variable は日本語環境だと 「変数へ昇格」となります。

f:id:hiyokosabrey:20210620123707g:plain

 

この変数を TimerHandler と命名。制御するので ハンドラー です。

f:id:hiyokosabrey:20210607235159p:plain

こうしておくと Set Timer by Event ノードが見えないところでやってるタイムカウントに介入することができます。

いろいろ制御できるのですが、今回やりたいのは、タイマーのキャンセル。

 

ノードだと Clear and Invalidate Timer by Event というノードになります。

f:id:hiyokosabrey:20210608000352p:plain

この辺のワードは WebでJavaScript を経験された方ならなじみ深いかもしれません。

f:id:hiyokosabrey:20210608000412p:plain

 

これを、回答ボタンイベントのところにつなぎます。

f:id:hiyokosabrey:20210620123319p:plain


タイマーが動いている間に、回答ボタンを押すとタイマーをなかったことにします。

これで完成!

コンパイルして保存したら再生してみましょう。

 

youtu.be

 

最後にちょっとだけ

秒数の指定を変数にしておきます。

f:id:hiyokosabrey:20210620141513g:plain

調整しやすくするためと、うっかり防止と、タイムボーナスなんかの対応に使用します。

この方法で変数を作ると、Default Value に自動的に値が入れられます。(※コンパイル後に確認可能)

f:id:hiyokosabrey:20210608002311p:plain

この値を変更してコンパイルすると、タイマーの時間を自由に変更できます。

 

 

おつかれさまでした!タイマーの実装完了です。

ボタンを押して遷移するのに比べて難易度が上がった感じがしますね。

 

いろんなタイマーを紹介してみたいのですが、先に進まなくなりそうなのでここまでにします。

リクエスト頂ければどこかでぶっこみましょう。

 

わかりにくいとか質問やツッコミなどあれば、このブログのコメント機能かTwitterにてお待ちしています。

 

ではでは

今回はこの辺で

ステキなタイマーライフを!

そうだ、UE4でQUIZゲームを作ろう《おまけ編》ボタンのデザインをどうにかする

 UE5の早期アクセスが公開されましたね。まだ触れていないので祝祭のツイートを眺めてるとマウスを操作する中指がつりそうです。UIがスッキリしてモダンな雰囲気を醸しているのがなんだかさみしくもあります。

 UE4のアイコンはそれなりに丁寧で考え抜かれてる感があって好きです。似たような機能を差別化するには、ある程度情報量が必要で、UE5の開発者がどんな解決を見せてくれるかとても興味があります。

 パネルの開閉に期待です。シングルモニターでの作業が捗りそうな予感。

 エディタとしての操作方法が変わっても、UE4での経験値はそのまま引き継げそうな話もチラホラあるので、安心してUE4を触っていこうと思います。

 

 

単純な構造ではあるけどひとまず動くものができたので、見た目に手を入れていこうと思います。

f:id:hiyokosabrey:20210529105931p:plain

UMGに馴れるのを主軸にして書いていこうと思っているので、まずはデフォルトのボタンデザインから作りかけ感がにじみ出るのを抑えることにします。テクスチャを作れる環境が必要となります。PNGをブログに貼っていますので、右クリック保存ができれば利用してみてください。テクスチャのインポート操作についても説明しています。

 

 

今回の内容は、以下の2つの記事の内容を作り終えた後のおまけ編となっています。

limesode.hatenablog.com

limesode.hatenablog.com

 

 目次

 

 

Buttonの見た目を変える方法

UMGのボタンコンポーネントである  Button の見た目を変える方法は、デザインを変更したい Button を選んでDetailsタブから各種パラメータをいじっていくのが基本の操作になります。

公式ドキュメントにさらっと書かれています。→ スタイリング

f:id:hiyokosabrey:20210529113412p:plain

 

 Appearance(アピアランス)の項目を編集します。

f:id:hiyokosabrey:20210529110250p:plain

Normal ・・・ 通常時の見た目

Hovered ・・・ マウスカーソルが重なった時の見た目

Pressed ・・・ クリックした時の見た目

Disabled ・・・ 使用不可の時の見た目

 

それぞれ中を開けると

f:id:hiyokosabrey:20210529113149p:plain

Image ・・・ テクスチャをセット

Draw As ・・・ 描画する方法  None / Box / Border / Image の4種

Margin ・・・ Draw As が Box または Border の時に設定可能

Tiling ・・・ Draw As が Image の時に設定可能

 

Draw As の Box と Border は 古いところで Flashでは Scale9Grid 、Unityだと 9Slice と同じものです。四隅を引き延ばすので小さくミニマムなテクスチャで高解像度な見栄えが出来上がります。

Border は 9分割した中央部が描画されないので、描画負荷を下げたいときに指定します。

ボタンひとつにつき、Normal、Hoverd、Pressed、Disabled(※必要に応じて) 毎に、テクスチャセット、Margin再設定 なので、結構手間を必要とします。

f:id:hiyokosabrey:20210529204037p:plain

セットするだけで、このふるまいを得られるので安いかどうかは検討案件です。

f:id:hiyokosabrey:20210529121649g:plain

 

Disabled は無い想定で3種類のテクスチャを用意しました。

サイズは 64x64ピクセル

f:id:hiyokosabrey:20210529122119p:plain   tex_MoveBtnBase_Normal.png

f:id:hiyokosabrey:20210529122129p:plain  tex_MoveBtnBase_Hoverd.png

f:id:hiyokosabrey:20210529122139p:plain  tex_MoveBtnBase_Pressed.png

 

 ↑ ブラウザからDLしてご利用いただけます

 

ゲーム開発には可能な限り PNG を避けておきたいと考えているのですが、3分クッキング的にブログに乗せられるフォーマットとしてPNG にしました。

いろいろ理由があって書きだすと長くなるのでやめておきます。

UE4にはちょっとだけステキな機能があるので、PNGでもリスクが減るのはうれしい限り。

 

 

テクスチャをインポート

テクスチャが用意できたら、UE4へのインポートが必要です。

 

アセットが増えてきたので、テクスチャ専用のフォルダを作ります。

 

まずは、コンテンツブラウザの何もないところで右クリックして新しいフォルダを作成します。

f:id:hiyokosabrey:20210529124357p:plain

 

f:id:hiyokosabrey:20210529123940p:plain

Widget 専用テクスチャなので、 Widgets フォルダの中がおすすめ。

 

メッシュやテクスチャなど、外部のDCC系アプリでテクスチャを作成することになりますが、UE4で扱う場合、Windowsエクスプローラでファイルをコピーしたり移動するのはできません。かならず インポート という操作を経て、UE4内で使用可能なアセットに変換する必要があります。このアセットのことを中間データと言ったりします。

 

ファイル形式をもとに説明すると PSD は完全に作業データです。

ゲーム制作においては、TGA や PNG 、DDS も 中間データ に含みますが、しいて分類にするなら、テクスチャインポート用データといったところでしょうか。

 

ゲームハードやサービスごとにネイティブなデータ形式がそれぞれ存在します。

ゲームエンジンがパッケージを作る際にターゲットになったプラットフォームに合わせて最適化してくれます。

使い勝手のいい状態を維持しつつ、用途に応じたいろんなメタデータをくっつけたり、メモリ使用量をコントロールしたりするために、インポート という操作フローが必須なのです。

PSDのような自由度の高い作業データは、思い出や不安がたくさん詰まっています。

プロジェクトフォルダの中に直接PSDを置かないのは、そういった個人的な感傷を共有の場にコミットさせないということでもあります。そんなセンシティブで巨大なPhotoshopデータはそっとしておくワークフローになっているのが素敵です。

 

 

 

続きに戻りましょう

 

ダウブルクリックしてフォルダを開いたら

また、何もないところを右クリックします。

f:id:hiyokosabrey:20210529124501p:plain

Import to ~ (~は今開いている場所=フォルダパス)を選択すると、Windows形式のファイル選択ダイアログが出てくるの、インポートしたいPNGファイルを選択します。

f:id:hiyokosabrey:20210529174743p:plain

開くと

コンテンツブラウザにアイコンが現れます。

f:id:hiyokosabrey:20210529175201p:plain

ダブルクリックするとインポート設定のダイアログが開きます。

f:id:hiyokosabrey:20210529125219p:plain

確実にチェックしておきたいのが、品質 と ミップマップ

 

まずは上から

f:id:hiyokosabrey:20210529175544p:plain

UMGで使用するため、

Compression Settings は UserInterface2D(RGBA) を選択します。

 

次は、サイズとPNG、sRGB対策

f:id:hiyokosabrey:20210529175935p:plain

Power Of Two Mode は、自動判別されるので、基本気にしなくても大丈夫ですが、2のべき乗の対応が必要になればここを変更します。強制的に2のべき乗サイズのテクスチャにできます。

 

PNGをインポートした場合に限り、Padding Color が大事になります。

Photoshopが出力するPNG形式は、完全透明の部分のカラーが白になるので、BC5などピクセル圧縮が掛かると、意図しない白いゴミピクセルがうっすら見えることがあるためです。表示されたときにフリンジのようなゴミピクセルが見えたら、このPadding Colorを変えてみてください。

 

普段のPhotoshopでの作業はカラーマネジメントを変更しない限り sRGB 環境になっているので、チェックがついている状態できちんと見えていればOK。

f:id:hiyokosabrey:20210529182654p:plain

 sRGBに応じた補正が不要なリニアなデータを作成した場合は、このチェックを外します。

 

 

次は Level Of Detail

f:id:hiyokosabrey:20210529182947p:plain

これがミップマップを生成するかどうかの設定です。

ゲームの描画は基本リアルタイムレンダリングで、カメラからの距離と、ポリゴン面の角度に合わせて、最適なテクスチャの解像度を動的に変更する仕組みがあります。その仕組みに対応するために事前にいくつかの解像度のテクスチャを作ってしまいます。

ゲーム中にリアルタイムに作るのは負荷が大きいので、インポート時に作ってしまえというわけです。内容は単純でオリジナル面積の1/4、1/16、1/64 ・・・と、何段階かの縮小テクスチャが作られ並べられます。

 

2D表示が主な UI はUMGのキャンバスに描くのでカメラは存在しません。ミップマップは不要なのです。作ったテクスチャにさらにミップマップ用のデータが追加されるとなると、データ容量がもったいないので、Mip Gen Settings は NoMipMaps を選択します。Gen はおそらく Genarate = 生成 の略記でしょうね。

64x64とか 256x256、1024x1024 みたいなべき乗の正方形テクスチャをインポートすると、自動で ミップマップを生成する設定になっているので、必ず確認しましょう。

 

ちなみに、テクスチャサイズを長方形にしたり2のべき乗でないサイズにすると、自動的に NoMipmaps にされ変更できなくなります。

 

Texture Group はテクスチャとしての用途を明示しておくことで、強制的なクオリティコントロール時に効果を発揮します。ここは UI を選択しておきましょう。

 

 ・・・

 

ひとまず大事なインポート設定は以上です。

特殊な状況じゃなければ、通常のテクスチャの場合はこれで問題は起こらないと思います。

残りの必要なテクスチャをインポートしましょう。

 

テクスチャ一枚ごとにちまちま設定するの大変という場合は 一括して行う方法もあります。

コンテンツブラウザで複数選択して、右クリック

Asset Actions > Bulk Edit via Property Matrix... が便利です。

f:id:hiyokosabrey:20210529201012p:plain

 使い方は今回は説明を省きますので、興味のある方は 公式ドキュメント かこちらをどうぞ。

unrealengine.hatenablog.com

 

 さあカスタマイズを始めようか

必要なテクスチャをインポート出来たら、

f:id:hiyokosabrey:20210529202459p:plain

Button の設定を編集していきましょう。

f:id:hiyokosabrey:20210529204037p:plain

Image にインポートしたテクスチャをセットします。検索で探してもいいし、コンテンツブラウザからの ドロップも便利。

 

Image Size はテクスチャをセットした際に自動で読み取ってくれるので基本放置。

 

Margin  は 0.25 で問題ないデザインなので、そのままにしています。

 

Disabledの下にある、~ Padding というパラメータは、クリックした際に凹む動きを実現する数値です。WEB の CSS で見かけることも多いかな。マイクロインタラクションってやつで、クリックした感が出るので地味にありがたい設定です。動いてほしくないときは、Normal Padding の値と、 Pressed Padding の値を同じにします。

SEの設定もできます。

 

 

これでようやくボタンひとつぶんの設定完了。

まじか! これを1個1個設定するの?なんかメンドクサくない?

はい。がんばれー!

 

で、ここまでは、マニュアル通りの答え。

 

とはいえ効率悪いよね?

ゲームのプロトタイプを作るとき、最初からおしゃれでいい感じのデザインで作ることはマレです。まずはアリものでアイデアが消えないうちにサクッと作りたいものです。

とはいえ、見た目でテンション上がるのは間違いないので、少しでも見映えはよくしたい。でもコストはかけたくない。

 

で、ここからは、ゲーム開発者としての答え。

後からボタンのデザインを差し替える方法を紹介します。

一時的に解決する方法と、後々のことを考えてメンテナンスできる形に変更する方法があります。

 

今判明している方法を3つご紹介。

  

 

まず、手っ取り早くコピペで!

設定の済んだ Button の Details > Appearance > Style のところで右クリックすると小さなメニューがポップアップするので、Copy を選びます。

f:id:hiyokosabrey:20210529210529p:plain


次に、設定のされていない Button で 同じように Style に 今度は Paste を選びます。

f:id:hiyokosabrey:20210529210543p:plain

これだけで移植できます。

この方法はデザインを変更するたびに、複数のアセットを開いて編集する必要があるのと、うっかりペーストし忘れが起こるかもしれないので注意が必要です。

 

 

オリジナルのButtonに差し替える!

新しくButtonアセットを作って、それと入れ替えます。

f:id:hiyokosabrey:20210529212154p:plain

そうすれば、このアセットをひとつ変更するだけですべてに反映されます。

問題なのは、入れ替える際、OnClickなどのButtonにまつわるイベントが解除されてしまうことです。

差し替えにかかる手間はこの一度きりなので、後々のことを考えてキリのいいところで一気にやってしまうのも手です。

 

作り方は、

コンテンツブラウザの何もないところで右クリックして Blueprint Class を選択

f:id:hiyokosabrey:20210529212600p:plain

 

Class 選択のダイアログがでてくるので、 button で検索

f:id:hiyokosabrey:20210529213027p:plain

ヒットした Button をハイライトしたら、Select ボタンをクリックします。

 

f:id:hiyokosabrey:20210529213253p:plain

適当に名前を付けるとアイコンが変化します。

f:id:hiyokosabrey:20210529213455p:plain

ダブルクリックして編集します。

f:id:hiyokosabrey:20210529213827p:plain

キャンバスが無く、Detailsタブも Appearance が一番上にいます。

ちょっと様子が違うようですが、スタイル設定をいじっていきます。

カスタマイズが終了したらコンパイル

保存したら閉じてもOK。

 

ではタイトル画面のWidgetを開きます。

f:id:hiyokosabrey:20210520230318p:plain

Designer モードにすると、左の Common リストのところに さっき作った Button が追加されているので、キャンバスにドロップします。

f:id:hiyokosabrey:20210529235448p:plain

じつはこれ、この後削除します。リプレイスするために一時的に必要になるためです。

 

ヒエラルキーの中で先に置いてあった、Button を選択して右クリックメニュー

Replace With... からの Replace With 作ったやつ_C を選択。

f:id:hiyokosabrey:20210530000212g:plain

入れ替わりました。

f:id:hiyokosabrey:20210530001645p:plain

 

ドロップしたやつは削除します。ついでに文字の色も見やすくなるよう変更。

f:id:hiyokosabrey:20210530001712p:plain

ここでコンパイルしてみると・・・!

f:id:hiyokosabrey:20210530001903p:plain

どうやら少々機嫌を損ねてしまった様子。

編集モードを Graphに替えます。

原因はこれでした。

f:id:hiyokosabrey:20210530002043p:plain

Button が別の Button に替わってしまったので、この OnClicked イベントが無効になってしまいました。

ここも差し替えます。

 

Variables リストにある、新しい Button を選択した状態で、

f:id:hiyokosabrey:20210530002548p:plain

Detailsタブの下のほうにある 緑色のボタンをクリック。

f:id:hiyokosabrey:20210530002702p:plain

グラフに新たな On Clickedイベントのノードが現れるので、古いのと交換します。

f:id:hiyokosabrey:20210530003153p:plain

 

f:id:hiyokosabrey:20210530003350p:plain

 

これでコンパイルできれば大丈夫。

f:id:hiyokosabrey:20210530003550p:plain

 

この方法だと、確実に差し替わるので、今後のデザイン変更にも強い構造になりますが、ブループリントもそれなりに編集することになるので、状況によっては手間取ることもあると思います。

 

デザインの差し替えを想定するなら、先に自前の Button をデフォルトの状態のままで組んでいくのはとても効率が良い気がします。

 

 

いろんなデザインを試したい!

もう一つデザインを差し替える方法があります。

ブループリントを使ったコピペ方式のようなものです。

手でコピペするのと同じで局所的な対処になるのですが、デザインの付け替えが気軽に行えます。

新しく作ったオリジナルボタンアセットをキャンバスにドロップします。

f:id:hiyokosabrey:20210530104901p:plain

すぐに 非表示にしておきます。

f:id:hiyokosabrey:20210530105003p:plain

同じ非表示でも Hidden より Collapsed の方が描画の負荷が少ないです。

この設定は、レイアウト作業中には反映されなくて、ゲームをプレイすると反映されます。

 

編集モードを Graph にします。

Variables リスト から Button をドロップ。

f:id:hiyokosabrey:20210530105925p:plain

それぞれのGetノードから、スタイルに関するノードを取り出します。

styで検索すると見つけやすいです。

 

スタイルを上書きする Set Style ノードは2つあります。

fアイコンのついた方が関数タイプで、複数の Button に対して対応可能。

青い コッペパンの形のアイコンの方は自身のパラメータ専用なので、1対1 にする場合。

今回は 関数タイプにします。

f:id:hiyokosabrey:20210530110759p:plain

 

スタイルを読み出す Get Style ノード

f:id:hiyokosabrey:20210530110750p:plain

 

取り出したノード同士をつなぎます。

f:id:hiyokosabrey:20210530111852p:plain

 

 これを Event Pre Construction につないで確認してみましょう。

f:id:hiyokosabrey:20210530112053p:plain

Designer モードにしてから コンパイルすると変化する瞬間が見れます。

f:id:hiyokosabrey:20210530112946p:plain

いくつかのデザインを用意してからキャンバスに非表示設定で並べておいて、つなぎ替えるだけで、結構手軽に見た目を変えられます。しかもスタイルだけを差し替えるので、On Clicked などのButtonイベントはそのままなのもうれしい。

デザインを検討している段階では助けになるのではないでしょうか。

 

不要なアセットが増えるのと、Get → Set の処理が負荷になるのを放置するのはプロジェクトにとって迷惑になる恐れがあるので、デザインがFIXしたら、タイミングを見てお掃除はしたほうがよさそう。

削除する際に警告が出ることがあります。

f:id:hiyokosabrey:20210530115130p:plain

誰か使ってそうだけど、ほんとに消していいの?

 

 

最近のAAAクラスのゲームは、アクセシビリティにも配慮をするのが当たり前みたいな空気になってきた感があるので、この方法を使うと、色覚特性に合わせたボタンデザインを用意して、オプション設定を見て差し替えることができます。むしろモダンな実装方法になっていくかもしれない。

 

 

適用していく

とりあえずで、この3つの方法で一番試しやすそうな方法を実践してみてください。

 

今回の用意した緑のボタンデザインは、画面遷移を伴うところに使いたいので、クイズの回答ボタンは別のデザインが好ましいです。

 

改めて

メイン画面の 回答ボタン のテクスチャも用意しました。

f:id:hiyokosabrey:20210530120812p:plaintex_BtnBase_Normal.png

f:id:hiyokosabrey:20210530120822p:plaintex_BtnBase_Hoverd.png

f:id:hiyokosabrey:20210530120831p:plaintex_BtnBase_Pressed.png

 

このデザインだと、Margin の値は 0.25 ではなく 0.5 になります。

Button のサイズも 縦方向は このテクスチャに合わせて 84 に変更したりしてます。

その辺は 見た目にボケたり、ガビったりしなければOK。

 

差し替えが面倒に感じたので、ひとまずブループリントで差し替える方法を採用してみました。SetStyle を関数タイプをにすると便利ですf:id:hiyokosabrey:20210530122321p:plain

 

 

 このようになりました

youtu.be

 

いかがでしたでしょうか。

ずいぶん 見た目に仮っぽさが減ったと思います。

このUMGの Buttonコンポーネントについては、まだ知らない仕様や賢い使い方がありそうなので、発見できれば記事にしていこうと思います。

 

個人的にこの手の『エンジンに最初から付いてるコンポーネント』系は、機能が豊富すぎて敬遠してしまいがちなんですが、そこはEpicさんなんで無駄のない仕様に仕上がっていると信じてます。いまのところは。

 

 

今回のおまけ編はここまでです

わかりにくいとことか、ツッコミなどあれば、このブログのコメント機能か、Twitterにてお待ちしています。

あとリクエストとかもあればお待ちしてます。

 

ではでは

ステキなUMGライフを!

 

 

そうだ、UE4でQUIZゲームを作ろう《おまけ編》いーなむで切り替えをわかりやすく

いーなむを使って遷移をわかりやすくしよう。します。いや、しませんか?提案させてください。ということで、先日のクイズゲームを作ろうという記事で、WidgetSwitcher を使って複数のWidgetを紙芝居的に入れ替えるというのを作りました。そのとき 0、1、2みたいに番号で管理していたので、後から忘れてしまっても大丈夫で、わかりやすくするしくみを導入したいと思います。

今回は 開発手法的なテクニックの紹介になるので、特に機能が増えたり、見た目が変わることはありません。変わるのはブループリントのノードです。関数ノードを作ります。

 

今回の内容は、以下の2つの記事の内容を作り終えた後のおまけ編となっています。

 

limesode.hatenablog.com

limesode.hatenablog.com

 

 目次

 

 

 

いーなむを作ろう

まず専用のアセットを用意します。

コンテンツブラウザの何もないところで右クリックします。

リストメニューから Blueprints > Enumeration を選択。

f:id:hiyokosabrey:20210525233127p:plain

f:id:hiyokosabrey:20210526004846p:plain

EScreenState という名前にしました。

EngineContent内を見てみると、頭に大文字の E を付けるのが慣例っぽいです。

これをダブルクリックしてエディタを開きます。

f:id:hiyokosabrey:20210526010300p:plain

右上の New ボタンをクリック。

今回は 4つの画面Widgetがあるので 4回クリック。

f:id:hiyokosabrey:20210526010427p:plain

Display Name と書かれたところに、いい感じに分かりやすくなるような名前を入力します。

WidgetSwitcher に登録した順番を元に名前を付けます

f:id:hiyokosabrey:20210526011326p:plain

 

f:id:hiyokosabrey:20210526011945p:plain

 wb_Title (タイトル画面) Title
 wb_Main(クイズ画面) Main
 wb_Right(正解演出)Right
 wb_Wrong(誤答演出)Wrong

 

後でWidgetSwitcherの順番を入れ替えることになった場合でも、入力しなおす必要はありません。右端の▲▼ボタンでここのリストも順番の入れ替えが可能です。

ここでしっかりと 1 対 1 に紐づいていれば大丈夫。

例えば、wb_Main2 が増えました~ しかも最後じゃなくてMain の次にしたいです~

という事態になっても、ヒエラルキーの順番を見ながら修正します。

 

 

いーなむを使ってみよう

QuizGame のWidgetを編集します。

f:id:hiyokosabrey:20210520233701p:plain

 

エディタを開いたら、Graphモードにします。

 f:id:hiyokosabrey:20210526213634p:plain

 

タイトル画面のボタンとバインドしている部分、ここのカスタムイベントにつながっているノードをまとめて選択状態にしたら、

f:id:hiyokosabrey:20210526213954p:plain

その上で右クリックして メニューから Collapse to Function を選択。

f:id:hiyokosabrey:20210526214123p:plain

すると、New Function ~ という1つのノードに変化しました。

f:id:hiyokosabrey:20210526215317p:plain


これは、関数化 という操作になります。

同じ仕事(タスク)を別の場所なんかで繰り返し行うときに、関数(ファンクション)としてまとめておくと、何度も同じノードをたくさん置かなくても、関数を一つ取り出してつなぐだけでスッキリします。しかも仕事の内容に名前を付けることにもなるので、あとからブループリントを見たときにも何をしてるかわかりやすくなります。

Photoshop で例えると アクション がイメージ的に近いです。

 

まずは New Function の名前を変更します。

変え方は 2通り

エディタ左 My Blueprintタブ の Functions リストから 右クリック > Rename する方法

選択して F2キーでも同じようにリスト内で変更することができます。

f:id:hiyokosabrey:20210526215737p:plain

もう一つは、この関数を編集している最中に変える方法。

 

このノードをダブルクリックします。

f:id:hiyokosabrey:20210526220404p:plain

関数の中だけのグラフに切り替わります。

f:id:hiyokosabrey:20210526220352p:plain

左端にある紫色のノードを選択して、右上の Detailsタブからリネームできます。

関数化したら、そのまま編集する流れになることが多いので、ひと手間減るかどうかぐらいの差でしかないですが、一応 2通りの方法を紹介しました。

 

ここは、WidgetSwitcher の切り替えを行っていたので、changeScreenState としましょうか。

続いて、そのまま 少し下にある、 Inputs というカテゴリの +ボタンをクリックします。

マウスオーバーすると +New Parameter というボタンに変わります。

f:id:hiyokosabrey:20210526221017p:plain

クリックすると、何やら出てきました。

f:id:hiyokosabrey:20210526221130p:plain

イベントディスパッチャーを追加したときにも、同じような操作をしました。

これはこの関数が受け取るパラメータ(引数=ひきすうとも言います)を追加する操作です。

デフォルトだと Boolean 型が出てくるのですが、すでに別のタイプをいじったことがあると、上の画像と違うのが出ることがあります。

 

この ▼ のついた プルダウンリストを開けて、用意してある いーなむ を探します。

f:id:hiyokosabrey:20210526004846p:plain

f:id:hiyokosabrey:20210526222217p:plain

これを選択します。ついでに 名前も NewScreenState に変更しました。

f:id:hiyokosabrey:20210526222404p:plain

 

グラフ上ではこうなります

f:id:hiyokosabrey:20210526222526p:plain

最終的に、この NewScreenState のピンと、 Index のピンをつなぐわけですが、方が違うので、キャスト(型変換)が必要です。

 

ところが、ドラッグしても 互換性がないと突っぱねられます。

f:id:hiyokosabrey:20210526222907p:plain

ここは自動ではやってくれないのです。

しかたがないので、手動でキャストするノードを取り出します。
toint で検索。Integer形へ という英文で書くと  to Int  が元です。

f:id:hiyokosabrey:20210526223544p:plain

変換アダプタのようなものですね。

f:id:hiyokosabrey:20210526223633p:plain

無事つながりました。

これで関数は完成です。

 

元のグラフに戻るには、タブを切り替えます。

f:id:hiyokosabrey:20210526224243p:plain

最初からあるグラフは、イベントグラフ EventGraph という名前がついてます。
ブループリントの編集に慣れてくると、いろんな関数やらマクロやらを開くことが多くなるので、編集が終わったら閉じるようにするとEventGraphに戻りやすくなります。

 

戻ってきてみると、

f:id:hiyokosabrey:20210526224857p:plain

あらまぁ 少し見ない間に~ てな見た目になります。

 

かつての様子 ↓

f:id:hiyokosabrey:20210526225742p:plain

 

いーなむ を入力のパラメータにすると、プルダウンメニューが追加されました。
ここはタイトル画面のスタートボタンが押されたら、メインの画面に遷移する という処理なので、Title を Main に変えます。

f:id:hiyokosabrey:20210526225332p:plain

 

ここで再生して問題ないかテストしてみましょうか。

 

問題なく動作すればOK。 あとは 似たような処理を見つけて入れ替えていきます。

グラフを見てみるとWidgetSwitcher の切り替えをしているところが3か所あります。

f:id:hiyokosabrey:20210620114758p:plain

ここを入れ替えていきましょう。

 

関数ノードを取り出すのは、リストからドロップしてもいいし、

f:id:hiyokosabrey:20210620114207p:plain


何もないところで右クリックして検索、でも取り出せます。

f:id:hiyokosabrey:20210526232747p:plain

 

f:id:hiyokosabrey:20210620114419p:plain

f:id:hiyokosabrey:20210526233127p:plain

 

すごくわかりやすくなったと思いますが、いかがでしょうか? 

 

いーなむは、インデックスのように数字で管理しているものに対して順番にわかりやすく名前を付けることができるのです。

今後 切り替えるものが増えた時も、いーなむアセットを編集するだけで済みます。

f:id:hiyokosabrey:20210526011945p:plain

これで 切り替えるときに、あれ?何番だっけ?という悩みが解決します。

さらに、このいーなむエディタの Description (説明)欄に書き込んだメモが、マウスオーバーで表示されるという新設設計。

f:id:hiyokosabrey:20210527001716g:plain

ぜひご活用ください

 

今回のおまけ編はここまでです

 

ここからはおまけのおまけ

 

 

逆引きで確認する方法 (おまけのおまけ)

デバッグするときの確認で便利なのが、番号を 文字 に戻す方法。

関数が呼ばれるたびに、PrintString したいと思います。

 

関数の中身に細工します。

f:id:hiyokosabrey:20210526234627p:plain

ちょっと引くぐらいキャストしまくってます。

 

WidgetSeitcher をGetタイプで取り出して、そこから

Get Active Widget Index で現在アクティブな(表示されている)番号を取り出して、

f:id:hiyokosabrey:20210526235824p:plain

いったん Byte型(バイト)にキャスト

f:id:hiyokosabrey:20210526235411p:plain

今度はバイトから いーなむ EScreenState にキャスト

f:id:hiyokosabrey:20210526235421p:plain

そこからようやく String型(ストリング=文字列)にキャストしてもいいし、

PrintString ノードにつないでも、ここは自動でキャストしてくれます。

f:id:hiyokosabrey:20210526235545p:plain

 

こういう機能追加や改造がしやすいのも関数化するメリットだったりします。

 

再生して確認してみましょう。

f:id:hiyokosabrey:20210527000022p:plain

 

なんか開発してるって感じになりませんか?

PrintString はいろいろ動作確認のときに大変便利なノードです。

今どうなってる? って時に役に立ちます。


 

今回は以上です

わからないところや突っ込み、リクエストなどなどあれば、このブログのコメント機能かTwitterにて

 

ではでは

ステキななUMGライフを!
 

 

そうだ、UE4でQUIZゲームを作ろう《組み立て編》

続きの記事になります

 

limesode.hatenablog.com

 

 

前回の記事ではクイズゲームに必要な表示を、Widgetブループリントというアセットで用意しました。今回は全部を組み合わせて動くようにします。

 

目次

 

 

その名をQuizGame

仕上げというか材料を入れて煮込む鍋のような存在として、最後のWidgetブループリントを一つ追加します。名前を wb_QuizGame としました。

このWidgetブループリントは、ゲームを動かす要となるアセットになります。

今まで用意してきたものはパーツです。

f:id:hiyokosabrey:20210519013532p:plain

さっそくキャンバスに、用意したWidgetを置いていきます。

まずは背景から。

 

Paletteタブ の User Created カテゴリに 作ったWidgetたちが並んでいます。

ここから wb_BG をキャンバスにドロップします。

f:id:hiyokosabrey:20210519014726p:plain

こうやって、Widgetアセットは他のWidgetでも再利用できたりします。

最近Web界隈?で話題のアトミックデザインというやつが、UE4でも扱うことができます。ゲームUIの開発では修正や調整の効率化のためにいろいろ試行錯誤はしていて、『アセット開発』などという言葉が出てきたあたりから本格化した印象ですね。

 

 余談はさておき

サイズがおかしいのでアンカーの設定を変更して拡げてやります。

f:id:hiyokosabrey:20210519234844p:plain

画面いっぱいにします。

f:id:hiyokosabrey:20210519235016p:plain

 

次に、Widget Switcher を取り出します。
Paletteタブ の Panelカテゴリにあります。

f:id:hiyokosabrey:20210519235412p:plain

この Widget Switcher が事前に用意しておいた Widgetたちの器になります。

これも、上の背景(wb_BG)同様にアンカーで画面いっぱいまで拡げます。

 

まだ中身が無いので入れていきます。

f:id:hiyokosabrey:20210519235016p:plain

 

Button の中に Text を入れたように ぽいぽいっとドロップします。

ただし順番が大事なので、今回は以下のように決めました。

 

 ① wb_Title (タイトル画面)
 ② wb_Main(クイズ画面)
 ③ wb_Right(正解演出)
 ④ wb_Wrong(誤答演出)

 

f:id:hiyokosabrey:20210520002035p:plain

WidgetSwitcher が表示するのは常に1つ。それを番号で管理します。

そのために登録順が重要になってくるのです。

タイトル画面が表示されていればバッチリです。

 

WidgetSwitcher を選択した状態で Detailsタブ を見てみましょう。

Switcher というカテゴリに Active Widget Index というパラメータがあります。

f:id:hiyokosabrey:20210520003201p:plain

ここを 0~3 の数字で変更してみてください。

数字を入力してEnterキーを押すと切り替わるのがわかります。

確認が済んだらタイトル画面からゲームを始めたいので 0 に戻しておきます。

 

ちょっと慣れないといけないのですが

プログラミングの世界では、番号を振って管理するものはたいてい

ゼロ始まり です。ゼロ番からナンバリングします。

なので、

 ① wb_Title (タイトル画面) → Index = 0
 ② wb_Main(クイズ画面) → Index = 1
 ③ wb_Right(正解演出) → Index = 2
 ④ wb_Wrong(誤答演出) → Index = 3

となっています。

 

ここでレイアウト作業は終了です。編集モードを Graph に変えましょう。

f:id:hiyokosabrey:20210520004016p:plain

Designerモード同様に、エディタ左にあるリストから取り出します。

まずVariables タブから  WidgetSwitcher を探してグラフにドロップします。

f:id:hiyokosabrey:20210520010703p:plain

ドロップする際に、ちいさなポップアップが出るので、Get~ の方を選びます。

f:id:hiyokosabrey:20210520011115g:plain

これが、『Getノード』のカタチです

このノードの右にある青い◎からドラッグします。

指を離したところでコンテキストメニューが出てくるので、上の検索フォームから  active と入力します。

リアルタイムにフィルタリングされるので、

Set Active Widget Index を探して選択します。

f:id:hiyokosabrey:20210520012813g:plain

これで、「WidgetSwitcher に対して、Active Widget Index の値をセットするよ」 という意味のつなぎ方ができました。

この方法だと、関連のある候補から選ぶことになるので、無関係なものをつないでエラーといった事態が避けられます。ぼくがブループリントをオススメするポイントの一つです。

この仕様は、ドラッグして指を離した際のポップアップにあるチェックボックスで切り替えができます。Context Sensitive(文脈依存)のスイッチです。

f:id:hiyokosabrey:20210520222750p:plain

ここは有効のままにしておくのをオススメします。

 

このノードを、最初から並んでいる赤いノードにつないでみましょう。

f:id:hiyokosabrey:20210520223120p:plain

ブループリントは同じ色の 〇同士をつなぐのが基本になります。

そして、白いホームベースの形同士をつないでようやくノードからノードへ処理の流れができあがります。

この赤い Event Pre Construction ノートは特殊なノードで、コンパイルしたときに実行されるイベントになります。

 

試しに、上の画像のように、Indexの値を 0以外 に変えて、エディタを Designer モードに切り替えたら、コンパイルしてみましょう。

f:id:hiyokosabrey:20210520223955p:plain

WidgetSwitcherの表示が変わります。

f:id:hiyokosabrey:20210520223946p:plain

WidgetSwitcherの切り替え方法をなんとなく実感できたところで、編集中断。いったん保存します。

 

 

タイトル画面からの遷移

次に、タイトル画面のWidgetブループリントを編集します。

f:id:hiyokosabrey:20210520230318p:plain

ボタンをクリックしたときの挙動を作っていきます。

 

まずキャンバスに置いた Button を選択します。

f:id:hiyokosabrey:20210520230519p:plain

 

エディタ右側 Detailsタブをスクロールした最下段にある、緑のボタン On Clicked をクリックします。

f:id:hiyokosabrey:20210520230824p:plain

するとすぐさまエディタGraphモードに切り替わります。

 

f:id:hiyokosabrey:20210520231049p:plain

新しくイベントノードが現れました。

これはクリックした際に呼び出されて実行されるイベントノードです。

カッコの中は配置した Button の名前です。Designer モードでいつでも変更できますが、今回は一つしかレイアウトしていないので、命名についてはひとまず放置します。

 

つぎにイベントディスパッチャーを作ってこのイベントにつなぎます。

エディタ左側から Event Dispatchers を探して、右にある + ボタンをクリックします。

f:id:hiyokosabrey:20210520232544g:plain

ED_OnClicked と リネームしました。
これを、右のグラフにドラッグ&ドロップします。

指を離すと小さなポップアップが出るので、Call を選択します。

f:id:hiyokosabrey:20210520233017g:plain

これを、On Clicked の赤いイベントノードとつなぎます。

f:id:hiyokosabrey:20210520233223p:plain

これでクリックしたことを通知する仕組みが準備できました。

コンパイルして保存します。

 

QuizGameのWidgetを編集再開です。

f:id:hiyokosabrey:20210520233701p:plain

先ほどの接続を切ります。

白い5角形を右クリックして Breake~ を選択するか、

白いラインの上で、Alt キーを押しながらクリックしても切断できます。

f:id:hiyokosabrey:20210520234619p:plain

 

 

切れたら、エディタ左側に Variables というリストがあります。

そこに WidgetSwitcherに仕込んだWidgetたちが並んでいるので、さきほどイベントディスパッチャーを追加した wb_Title をグラフに取り出します。タイプは Get で。

f:id:hiyokosabrey:20210520234329p:plain

ノードの右にある〇(出力ピン といいます)からドラッグしてノードを検索します。

今度は、 bind と入力。

f:id:hiyokosabrey:20210520235548g:plain

そして、 Default > Bind Event to ED On Clicked を見つけて選択。

ここ似たようなやつが多いので慎重に。

このバインドノードと 赤い Event Pre Construction をつなぎます。

f:id:hiyokosabrey:20210521000011p:plain

 

つぎに、バインドノードの左下にある、□ Event からドラッグしてカスタムイベントノードを取り出します。Add Custom Event を選択。

f:id:hiyokosabrey:20210521001754g:plain

UE4は結構な数のイベントノードがあらかじめ用意されていますが、このカスタムイベントは、イベント処理を自由に作ることができる大変便利なノードです。

スタートボタンを押したときのふるまいをつくったので、PressStartButton と命名しました。

 

ノードの並びをちょっと整理しました。

WidgetSwitcher を切り替える Set Active Widget Index ノードの Index を 1 にします。

f:id:hiyokosabrey:20210521002442p:plain

そろそろプレビューして確認してみます。

コンパイルして保存します。

 

 

確認してみる

実際に動くかどうか確認するには、再生する必要があります。

メインウィンドウのPlayボタンを押すか Altキーを押しながら P キーで今のレベル(見えている状態のワールド)がゲームプレイ状態になります。

f:id:hiyokosabrey:20210521003245p:plain

今はまだ何も起こらないので、Widgetを表示できるようにします。

 

レベルブループリントを編集します。

メインウィンドウの上部にある Blueprints というボタンをクリックすると、プルダウンリストが出てくるので、 Open Level Blueprint を選択します。

f:id:hiyokosabrey:20210521004220p:plain

 グラフエディタが開きます。

f:id:hiyokosabrey:20210522005051p:plain

新しくノードを取り出します。

何もないところで右クリックして Create widget を検索。

f:id:hiyokosabrey:20210522005435p:plain

 

出てきたのはこんなノード ↓

f:id:hiyokosabrey:20210522005541p:plain

Class のところに wb_QuizGame をセットします。

 

セットする方法は2種類。

プルダウンから検索する方法と、コンテンツブラウザでアセットを選択した状態で白い矢印をクリックする方法。

f:id:hiyokosabrey:20210522010338p:plain

Return Value のピンからドラッグして、Add to Viewport ノードを取り出します。

f:id:hiyokosabrey:20210522011134p:plain


初めから置いてある Event BeginPlay ノードとつなぎます。

f:id:hiyokosabrey:20210522011148p:plain

これで準備完了、ではあるのですが、少しだけ安全対策を施しておこうと思います。

UE4 は UI のクリック対象ではない部分(例えばボタン以外)をクリックしてしまうと、背後のステージをクリックしたことになって、カメラをぐりぐり動かすことができるようになっています。そして、マウスカーソルが非表示にされてしまいます。フォーカスが移ってしまうんですね。
Shiftキー を押しながら F1 キーで戻ってきますが、慣れないと焦るので、今回はUI表示がメインの画面でもあるので、常時カーソルを表示するようにしてしまいましょう。

ノードを2つほど取り出してつなぐだけです。

 

まず何もないところをクリックして、Get Player Controller ノードを探します。

f:id:hiyokosabrey:20210523224029p:plain

f:id:hiyokosabrey:20210523224201p:plain

UE4触ってると、何かとお世話になるやつです。

次に ReturnValue から Set Show Mouse Cursor という変数を 取り出します。

f:id:hiyokosabrey:20210523224414p:plain

f:id:hiyokosabrey:20210523224940p:plain

いつもと様子の違うのが出てきました。

これは、 Player Contoroller が持っている変数に値を書き込もうとしています。

チェックをつけてつなぎます。

f:id:hiyokosabrey:20210523224821p:plain

これで安心。

 

コンパイルして保存します。保存は初めてになると思うので、以下のようなダイアログが出てきます。

とりあえず Widgetフォルダと同じ階層に名前を付けて保存します。

f:id:hiyokosabrey:20210522011617p:plain

 

 

保存できたら再生してみます。

 

f:id:hiyokosabrey:20210522013746p:plain

STARTボタンをクリックして切り替われば・・・

f:id:hiyokosabrey:20210522013810p:plain

バッチリです。

止めるのは Escキー か、 エディタ上部の Stopボタンです。

 

今回プロジェクトを新しく作っているので、UE4を起動すると基本の テンプレートレベルが開かれます。

引き続きこのレベルを使う場合は、毎回ダブルクリックして開くことになります。

最初から開いていてほしい場合は、Editメニューの Project Settings > Maps & Modes にある Default Maps で起動時のレベルを指定できます。

f:id:hiyokosabrey:20210522013623p:plain

 

 結構長くなってきた。

 

流れをまとめると

マウスのクリックを受け付けるWidget に イベントディスパッチャーを追加

ボタンをクリックした際に、イベントディスパッチャーを呼び出す(Call)ことにする

親のWidget は、 マウスのクリックを受け付けるWidgetに対して バインド(紐づけ)をする

イベントディスパッチャーが呼ばれた(Call)ら、バインドしている親Widgetに通知が行って、つながっているカスタムイベントを処理する

 

ことになります。

f:id:hiyokosabrey:20210522104943p:plain

 

イベントディスパッチャーは、バインドしてつながっている相手にだけ通知が渡ります。

自分からはバインドできません。される側になります。

なので、仕事の責任範囲が小さくできるぶん、作りが気楽にできます。

なんかあったらイベントディスパッチャー呼んどくか。あとは知らん。てな具合です。

他にも、

まだ親のほうで処理はつくられてないけど、将来的に必要って聞いてるから、イベントディスパッチャーを呼ぶとこを追加しておこう。というようなゆるい作りが可能です。

 

複数人で開発してる場合、

このタイトル画面Widgetのような場合、ボタンクリックとイベントディスパッチャー呼び出しのところを触らなければ、あとはお好きにどうぞ、とデザイナーにぶん投げることができます。ボタンの仕組みを変えたとしても、最終的にクリックした際にイベントディスパッチャーさえ呼ばれれば、あとは親が何とかします。または、この仮組みのようなWidgetをサクッと作ってプログラマに渡しておくと、ゲーム開発がスムーズになるのを少しは期待できます。

 

さてさて

WidgetSwitcherの切り替えもうまくいってるので、今度はメインの出題画面を仕上げます。

 

 

クイズの出題と回答ボタン

今回はチュートリアルということで、出題は固定の1問とします。

メインのWidgetを編集します。

f:id:hiyokosabrey:20210522114426p:plain

 

Designerモードにしたら、出題用の Text を選択します。

そして右上にある Is Variable を有効にします。

f:id:hiyokosabrey:20210522123302p:plain

最初から Is Variable が有効になっているものもありますが、Text については 無効になっているのが基本なので、必要に応じて チェックを付けます。

ついでに TextBlock_0 を TextBlock_Question にリネームしました。

f:id:hiyokosabrey:20210522123211p:plain

 

Is Variable の状態は

Graphモードに変えるとどう変わったか判明します。

f:id:hiyokosabrey:20210522142000p:plain

Is Variable を有効にすると言葉の通り、

Variables(変数)として扱うことができるようになります。

 

これを グラフに取り出します。Getタイプで。

そこへ、ドラッグして SetText(Text) ノードを探してやります。

f:id:hiyokosabrey:20210522142350p:plain

f:id:hiyokosabrey:20210522142550p:plain

この In Text ピンのところにテキストを入力できるので、問題文を入力してみます。

複数行にしたい場合はShiftキーを押しながらEnterキーで改行できます。

問題文を入力出来たら、 Event Construct につなぎます。

f:id:hiyokosabrey:20210522151814p:plain

世界三大料理として挙げられる 中華料理 と
フランス料理 あと一つは?

 

Event Pre Construct と違うのは、コンパイルしても実行されない点です。ゲームが再生されたときに実行されます。

コンパイルした後、Designer モードに切り替えても Text Block となったままなのが確認できます。

 

確認のため再生してみましょう。

コンパイルして保存したら、Playボタンを押すか、Alt + P です。

Startボタンをクリックしたらちゃんと反映されてました。

f:id:hiyokosabrey:20210522152533p:plain

 

次に回答ボタンを仕込んでいきます。

まずボタンの名前。

ただ配置しただけで放ってあったので名前を付けます。

そうすることでブループリントで扱う際にわかりやすくなります。

 

リネームの方法は2か所で変更できます。

エディタ左側のヒエラルキー内で右クリックして Rename を選ぶか、 F2キー

f:id:hiyokosabrey:20210522153148p:plain

もう一か所は、Detailsタブの一番上

f:id:hiyokosabrey:20210522153355p:plain

どちらで変更してもOK。

上から順番なのが分かるように、 0 1 2 3 とか A B C D 、1st 2nd 3rd 4th など連続するように名付けます。

続けて、Button の子供にした Text も内容を変更します。

この TextIs Variable を有効にして、Button と同じように順番がわかるように名前を付けます。

 

最終的にヒエラルキーはこうなりました。今回 ABCD を採用。

f:id:hiyokosabrey:20210522154152p:plain

これで、編集モードを  Graphモードに移行します。

 

f:id:hiyokosabrey:20210522154848p:plain

 

反復的な操作が増えてきたので、この辺から省略気味でいきます。

 

Variablesのリストに追加されているので、グラフに Getタイプでドロップしたら、

問題文同様に回答のテキストをセットします。

f:id:hiyokosabrey:20210522155527p:plain

一応再生して確認しておきます。

 

f:id:hiyokosabrey:20210522161005p:plain

よしよし大丈夫そう。

 

次に

回答ボタンを押したときに、反応できるように

OnClickedイベントと、イベントディスパッチャーを用意します。

OnClicked イベントは、 Detailsタブの一番下にある緑のボタンから作ると、編集モードが行ったり来たりして面倒なので、Graphモードで作成することにします。

 

まず Graphモードに切り替えて、Variablesリストにある回答用の Button~ を選択

f:id:hiyokosabrey:20210522161656p:plain

すると、エディタ右側の Detailsタブのところに、緑のボタンが現れるので、ここからも On Clicked イベントを作成することができます。

f:id:hiyokosabrey:20210522162223p:plain

スクロール動作が入りますが、編集モードが切り替わらないので、連続して操作するときにサクサク進んでいい感じです。

ここにイベントディスパッチャーを一つ用意してつなぐのですが、パラメータを追加したイベントディスパッチャーにします。

 

まずは +ボタンを押して追加します。名前を ED_Answer としました。

f:id:hiyokosabrey:20210620111505p:plain

選択状態にしておいて、Details タブにある、Inputs の欄にある+ボタンをクリックします。パラメータの名前を Judgment としました。タイプは Boolean です。

f:id:hiyokosabrey:20210522171635g:plain

このタイミングで、一度コンパイルします。

パラメータを追加したりパラメータ名を変えた場合はエンジン内での情報の更新が必要になるようで、グラフに取り出す前だとスルー出来ますが、取り出してからだと、エラーが出ます。

 

このイベントディスパッチャーをグラフに取り出します。

f:id:hiyokosabrey:20210522163546p:plain

OnClicked イベントにつなぎます。

f:id:hiyokosabrey:20210620112413p:plain


4番目が正解だったので、Judgmentのところのチェックボックス を True にします。

これでボタンをクリックしたときに、正解か不正解かという情報も一緒に伝えることができます。

 

これでこのWidgetブループリントは編集完了です。

コンパイルして保存します。

 

 

バインドそして判定結果へ

またQuizGameのWidgetを編集再開です。

f:id:hiyokosabrey:20210520233701p:plain

 子要素のWidgetに イベントディスパッチャーが追加されたので、バインドする必要が出てきました。

タイトル画面の切り替えと同じようにバインドしてやります。

 

出題画面のWidgetを Variables のリストから探してグラフにドロップします。

f:id:hiyokosabrey:20210522165726p:plain

バインドするイベントディスパッチャーを探します。

f:id:hiyokosabrey:20210620112607p:plain


タイトル画面遷移のバインドノードの次につなぎます。

f:id:hiyokosabrey:20210620112752p:plain

カスタムイベントの名前は Result としました。

自動で、Judgmentのピンが追加されています。

こうやってイベントディスパッチャーから値が送られてくるのです。

 

確認のため、Print String ノードをつないで再生してみましょう。

何もないところで右クリックして検索します。

f:id:hiyokosabrey:20210522173122g:plain

色の違うピン同士はつながらないのですが、キャスト(型変換)ノードを間に挟むことでつながることがあります。

よく利用するキャストは、自動で入れてくれるものが多いので助かります。

 

コンパイルして問題なければ再生してみましょう。

回答ボタンをいろいろ押すと、左上に true と false がどんどん下に向かって表示されます。一定時間が経つと消えます。

 

問題なければ、イベントディスパッチャーはうまく働いているようです。 

グラフに戻ります。

確認が済んだので、PrintStringノードは消して、今度は Branch (ブランチ)ノードをつなぎます。

何もないところで右クリックして、bran で検索すると絞り込めます。

f:id:hiyokosabrey:20210522200530p:plain

カスタムイベントと、つないでやります。

f:id:hiyokosabrey:20210620112924p:plain


ブランチノードは何もないところで B キー を押しながらクリックしても取り出せます。

これは条件によって処理の流れを分岐させるノードです。

右に True と False の実行ピンがあるので、ここに WidgetSwitcher の切り替えを行うノードをつなぎます。

f:id:hiyokosabrey:20210620113046p:plain


Index の値は、 WidgetSwitcherにセットした順番のWidgetを意味します。

 

 ① wb_Title (タイトル画面) → Index = 0
 ② wb_Main(クイズ画面) → Index = 1
 ③ wb_Right(正解演出) → Index = 2
 ④ wb_Wrong(誤答演出) → Index = 3

 

これで確認してみましょう。

コンパイルして再生します。

正解画面と不正解画面がうまく切り替わればバッチリです。

完成まであともう少し!

 

あと解決しなければいけない点は2つ。

  1. アニメーションが再生されない
  2. Nextボタンを押しても反応がない

 

2 はもう何度かやってきたのでイメージできると思います。

問題は 1 ですね

 

 

ブループリントインターフェイス

Widgetブループリントを作ったのと同じように、コンテンツブラウザの何もないところで右クリックして、 Blueprints > Blueprint Interface を選択します。

f:id:hiyokosabrey:20210522202708p:plain

IF_QuizGame と命名

f:id:hiyokosabrey:20210522202948p:plain

ダブルクリックしてエディタを開きます。

f:id:hiyokosabrey:20210522203345p:plain

右上を見てみると、名前を入力してほしくてウズウズしてる様子が伺えます。

f:id:hiyokosabrey:20210522203538p:plain

ブループリントインターフェイスは、関数を登録するところです。

といっても名前だけの。

 

イベントディスパッチャーと少し雰囲気が似ていて、中身がないのだけれど、存在できて、呼び出しも可能。呼ばれても何もしないので何も起こらない。一応存在はしてるので、呼び出す処理は先に用意できるし、エラーが起きない。中身は別の場所でオーバーライドして利用することができる。

なんとも不思議な存在。

 

とりあえず名前を付けてあげましょう。

StartAnim

としておきます。

f:id:hiyokosabrey:20210522204741p:plain

編集作業はそれだけです。

コンパイルして保存したら閉じましょう。

 

QuizGameのWidgetに戻ってちょっと確認してみます。

f:id:hiyokosabrey:20210520233701p:plain

 

グラフ上で、StartAnim を検索してみると ありました。

f:id:hiyokosabrey:20210522205204p:plain

さっそく取り出してみます。

f:id:hiyokosabrey:20210522205314p:plain

イベントディスパッチャーの Call タイプと同じ封筒のアイコンが右上についています。

これを 先ほどの ブランチノードで分岐した最後につなぎます。

f:id:hiyokosabrey:20210522205804p:plain

とにかく正解だろうが不正解だろうが、なんかわからないアニメーションを再生してよ、ということになります。

さて、だれに対して? 

 

それっぽい関数ノードは見つかったけど、さすがに対象を決めないと、コンパイルエラーになります。

この場合、 正解または不正解のWidgetブループリントが対象です。

さてどちらか?

 

表示されてる方(アクティブな方)

 

どうやって調べる?

こういう時役に立つのが、 get って検索することです。

きっと WidgetSwitcherに Set Active Widget Index なんてノードがあるんだから、Get なんちゃらもあるはずです。

 

ありました get だけだと 大量に出てきたので、get act とするとビンゴ!

f:id:hiyokosabrey:20210522211253p:plain

今アクティブになってるWidgetを教えてくれるノードです。

f:id:hiyokosabrey:20210522211401p:plain

このReturn Value の青いピンを、StartAnimにつなげばよさそうです。

f:id:hiyokosabrey:20210522211535p:plain

さっそくコンパイルして再生してみましょう。

 

・・・

 

はい。すみません。動くわけないですね。

 

でもコンパイルしてもエラーになりません。名前しかない関数なのに、アクティブなWidgetといっても、 wb_Right 、 wb_Wrong にはまだ StartAnimなんて関数はかけらも存在しないのに。

普通は対象アセットが持ってないものには、アクセスできませんし、そもそもつなぐことすらかなわないのです。

それをひとまずエラーにならずに済ませてしまうのが ブループリントインターフェイスなのです。

 

ちなみに上の間接的なつなぎ方を直接的につなぐとこうなります。

f:id:hiyokosabrey:20210620113222p:plain

これでコンパイルしてもエラーにはなりません。編集の順番を無視できます。

 

直接対象につながずにget Active Widget ノードをオススメしたいのは、処理の流れさえおかしくならなければ、WidgetSwitcher の中身の順番が変わっても関係ない点。

いろんなアセットやブループリント触ってるといちいちIndexがどうなってるかなんて把握できないし、忘れがちなので、こういった「今アクティブなやつ」みたいにフワッとした指示の出し方は結構気楽でいいのです。

 

 

で、そろそろアニメーション再生できるようにするか

ということで、wb_Right と wb_Wrong を編集します。

ついでに、Nextボタンの対策も。

f:id:hiyokosabrey:20210522213613p:plain

どちらも同じ内容なので、wb_Right をベースに書いていきます。

 

編集モードを Graphに切り替えると、 エディタ上部に Class Settings という大きなボタンがあります。

f:id:hiyokosabrey:20210522213943p:plain

これをクリックすると Details タブの内容が変わります。

f:id:hiyokosabrey:20210522214205p:plain

まん中付近に Interface というカテゴリがあるので、そこの Add ボタンを押して、今回用意した ブループリントインターフェイスを選択します。

 

f:id:hiyokosabrey:20210522214456p:plain


と、同時に左のMyBlueprintタブにも Interfaces というカテゴリが出現します。

f:id:hiyokosabrey:20210522214709p:plain


これ、ただのカタログのようなもので、グラフにドラッグできません。

f:id:hiyokosabrey:20210522214829p:plain

なので、オーバーライドします。

すぐ上にある Functions カテゴリの右上に Override というボタンがあるのでクリックすると長いリストが出てきます。

f:id:hiyokosabrey:20210522215212p:plain

その一番下に StartAnimがいるはずです。

選択すると グラフに イベントノードが出現しました。

f:id:hiyokosabrey:20210522215337p:plain

ここに、作っておいたアニメーションを再生させる処理をつなぎます

まず Variables > Animations から IN をGetタイプで取り出して、

f:id:hiyokosabrey:20210522215748p:plain

そこから
Play Animation ノードを探します。

f:id:hiyokosabrey:20210522220013p:plain

イベントとつなげばOK。

f:id:hiyokosabrey:20210522220106p:plain

 

 

あとは、ボタンクリック対応

イベントディスパッチャーを用意します。

タイトル画面の遷移と同じく特にややこしいこともしないので、ED_ButtonPressed とでもしておきましょうか。

f:id:hiyokosabrey:20210522220517p:plain

 On Clicked イベントを取り出して、イベントディスパッチャーとつないだら完成。

 

f:id:hiyokosabrey:20210522220703p:plain


コンパイルして保存したら、不正解用のWidgetも同じ様に仕上げます。

流れを振りかえると

  1. ClassSettings の Interface に Add
  2. Functions の Overrideボタンから StartAnim をノードを取り出す
  3. そこにアニメーションを再生させるようにつなぐ
  4. OnClickedイベントを取り出す
  5. イベントディスパッチャーを追加してつなぐ

です。

 

最後の仕上げ

Nextボタンのバインドをするので、

また QuizGameのWidgetに戻ります。

f:id:hiyokosabrey:20210520233701p:plain

正解、不正解の演出のあとは、再びクイズ出題画面に戻るようにします。

 

さて復習です。これをノーヒントでできるでしょうか?

f:id:hiyokosabrey:20210522222053p:plain

ちょっと離れたところとつながってます。

f:id:hiyokosabrey:20210522224829p:plain

 

ということで非情ながら次に進みます。

バインドした際に実行するカスタムイベントは、形態が同じなら共用できます。

パラメータがついたりして差異が生まれると共用はできなくなります。

f:id:hiyokosabrey:20210522225615p:plain

これで、正解の時も不正解の時もおなじ処理ができます。

ノルマとかのUI表示があれば、別々にしてもいいし、回答ボタンの時のようにBooleanのパラメータを使って分岐させるのもありです。

 

このカスタムイベントに WidgetSwitcher の切り替えをつないだら完成です。

f:id:hiyokosabrey:20210522230204p:plain

Index は 1 にしておきます。

コンパイルして問題なければ保存して再生します。

 

画面遷移が下のようにつながっているのが確認できれば完成です。

f:id:hiyokosabrey:20210522231342p:plain

 

 

youtu.be

 

おつかれさまでした

さすがに長かったですね。このページだけで 12,000文字に届きそうです。

 

まとめ

今回作ったものの仕様

複数の画面レイアウトを、それぞれWidgetブループリントとして作成

WidgetSwitcher を使って切り替えて表示

それぞれのWidgetからの通知はイベントディスパッチャーで受取り

それぞれのWidgetへの指示はブループリントインターフェイスを使用

 

このチュートリアルの効果

基本的なUMGの編集方法がわかる

キャンバスに置いたものをブループリントで扱う方法が学べる

複数の画面を手軽にプレビューできる仕組みが実践できる

各画面ごとに対して、軽いインタラクションを組み込むことができるようになる

・・・

といいな

 

 

最後に

理解範囲もボリュームもいい感じだと思ってるんですけど、いかがでしょうか。

もうしばらくアレンジやら、小ネタとかの記事を公開していくつもりです。

少しでも UE4の UI制作に 興味を持ってもらえたら嬉しいです。

 

 

わかりにくいところや質問、ツッコミ等あれば、このブログのコメント機能かTwitterにてお気軽にどうぞ。

自宅でしかレスできないので反応速度に関しては気長モードでお願いします。

 

ではでは

ステキな UMGライフを!

 

 

そうだ、UE4でQUIZゲームを作ろう《準備編》

UE4で試しに作ってみたらそれっぽいのができたやつ シリーズ第n弾

カウントしていないのでnです。まあいつもの癖です。

とある動画を見ていて、UMGに WidgetSwitcher というのがあって使えそうだなと思ったのと、UMGのチュートリアルの教材にクイズゲームはどうだろうかと以前より構想していたのがきっかけです。

 

とある動画というのはこちら


www.youtube.com

 

AdobeXD での画面遷移はアートボード間を行ったり来たりするのが基本なので、UE4の場合、1枚のアートボードを1つのアセット として扱えば XDで作っているかのようなワークフローが実現できそうな気がします。

なので、今回AdobeXDは使わずに、UE4の UMG を使ってAdobeXDのような感覚で画面作りにチャレンジしてみようかと思います。

XDの持つ快適な操作性はうらやましい限りですけどね。

 

この動画からひらめいたのと、AdobeXDを意識したのもあって、見た目がまんまな感じのものが仕上がりますが、そこは突っ込まないでいただけるとありがたいです。

 

 

画面構成はこうなります。

 

f:id:hiyokosabrey:20210522231342p:plain

 

 

今回の記事でフォーカスを当てたいのが下の2つ。

  • イベントディスパッチャー Event Dispatcher
  • ブループリントインターフェイス Blueprint Interface

 

別々のWidget間での連携プレーを実践するための、ほどよいチュートリアルにしたいなと思っているのですけどどうでしょうね。操作方法についてはなるべく易しく説明したつもりです。UMGに不慣れな方にチャレンジしてもらえると嬉しいです。

 

 

まず作るアセットは 7つ。

  1. バックグラウンド(共通)
  2. タイトル
  3. 出題&回答ボタン
  4. 正解演出
  5. 誤答演出
  6. ブループリントインターフェイス
  7. ゲーム画面

 

表示用のアセットを揃える《準備編》と、ブループリントで動かす《組み立て編》の2部構成で考えています。

いったん最小限の構造が出来上がったら、後日おまけの要素を追加する予定です。

  • 問題を増やせるようにする
  • 背景をにぎやかにする
  • タイマーをつける
  • ノルマを設定する
  • ゲームオーバー画面を作る

 

ではさっそく

 

 

目次

 

 

エディタを起動する

今回使用するUE4のバージョンは 4.26.2 です

f:id:hiyokosabrey:20210523102752p:plain

新規プロジェクトを作るところから書いていこうと思いますが、すでに日常のプロジェクトをお持ちで、わざわざそこまでという方は、Developerフォルダ内でも大丈夫です。

起動ボタンを押して出てくるダイアログ(下の部分)。

f:id:hiyokosabrey:20210515235423p:plain

Game を選んで、 Nextボタンをクリック

 

テンプレートは Blank を選びます。

f:id:hiyokosabrey:20210515235920p:plain

 

次に適当なプロジェクト名をセットして Create Project

f:id:hiyokosabrey:20210516000007p:plain

 

スプラッシュが出て、しばらく待つとエディタが起動します。

f:id:hiyokosabrey:20210516000306p:plain

 

 

フォルダを作る

画面下のコンテンツブラウザ内で右クリックして、フォルダを新しく用意します。

一番上にあります。

f:id:hiyokosabrey:20210516000913p:plain

 

フォルダ名はとりあえず Widgets という名前にしておきます。

f:id:hiyokosabrey:20210516003239p:plain


 ダブルクリックしてこのフォルダ内に入ります。

 

 空っぽだと、以下のような文言が表示されます。

f:id:hiyokosabrey:20210516001957p:plain

 

 

ウィジェットブループリントを作る

UE4において、UI表示を担当する仕組みがUMG(Unreal Motion Graphics)で、アセットのタイプは Widget Blueprint になります。

フォルダを作ったのと同じように右クリックして Widget Blueprint を探します。

今度は一番下の項目の中のさらに一番下にあります。辿りやすい。

f:id:hiyokosabrey:20210516002424p:plain

 適当に wb_BG と名付けました。

f:id:hiyokosabrey:20210516003252p:plain

ダブルクリックして専用のエディタを開きます。

 

 

バックグラウンド編

最初のWidgetは背景専用で作っていきます。

f:id:hiyokosabrey:20210516103627p:plain

 このエディタは、2つの編集モード に切り替えることができます。

右上に並ぶ2つのボタンで、オレンジ色にハイライトされているほうが現在のモードを表しています。

まずはこの Designer モードで 表示したいものを置いていきます。

 

 最初から CanvasPanel が一つだけ置かれた状態で編集を開始します。邪魔だと思えるくらいUMGに慣れるまでは、このCanvasが画面のサイズを表していると思って作業するといいと思います。

 

今回は背景ということで、まず左のPaletteタブから Common カテゴリの Image をドラッグします。

ドロップできる場所は2か所あります。

f:id:hiyokosabrey:20210516105648p:plain

作業の手間が少し変わる程度なので、どちらでもOK。

意味合いとしては、

 

キャンバスにドロップ

 置き場所を探りながら直感的に配置したい

 マウスで感覚的に位置を決めることができる

 

ヒエラルキーにドロップ

 親子関係(階層構造)を気にしながら配置したい

 座標がゼロリセットされた状態で配置される

 

一度配置してしまえば、座標の調整は、Detail(詳細)タブからも行えるので、どちらの方法でも大差ないです。後から親子関係を変えると表示位置が変わるので、調整の手間を惜しむなら、一考してからどちらかを選択するといいかも。

 

さてこの取り出した Imageパーツ のサイズと位置を整えるのですが、アンカー(Anchor)の設定をうまく活用したいと思います。

 

適当にキャンバスにドロップしたらこうなりました。

f:id:hiyokosabrey:20210516114033p:plain


右のDetailsタブにある Slot > Anchors にあるプルダウンをクリックします。

ポップアップウィンドウの中から右下のアイコンを選択します。

f:id:hiyokosabrey:20210516114227p:plain

このとき Ctrl キー 押しながらクリックするとラクチンです。

押さずにクリックすると下の画像のようになります。

f:id:hiyokosabrey:20210516121039p:plain

エディタ右にあるDetail(詳細)タブからパラメータを変更します。

f:id:hiyokosabrey:20210516121234p:plain

Offest ~ と書かれた部分は、選んだアンカータイプによって変化します。

今回は上下左右全てを 画面の端から何ピクセル というアンカーを選んだので、すべてをゼロにすると、画面にピッタリ合うようになります。

f:id:hiyokosabrey:20210516121522p:plain

Ctrl キー押しながら選択すると、このゼロを入力する手間が省けます。

レスポンシブな背景完成!

 

この Image パーツは主に画像をセットして使うことが多いのですが、今回はナシで進めます。シンプルなベタ色の四角として使えます。

 

カラーは Detailsタブの Appearance > Color and Opacity から変更できます。

f:id:hiyokosabrey:20210516135454p:plain

これで編集完了。

アセットを保存します。

エディタ左上のアイコンを Compile ボタン → Save ボタン の順でクリックすれば保存できます。

f:id:hiyokosabrey:20210516140803g:plain

ここでのコンパイルの実行は、実際に使える状態に仕上げるというイメージで捉えるとよいかと思います。

何か問題があると警告してくれます。

 

Saveが完了すると、アセット名の横についた * が消えます。

f:id:hiyokosabrey:20210516142804p:plain

保存したかどうかは、↑このタブと、

↓コンテンツブラウザでも確認できます。

f:id:hiyokosabrey:20210516143004p:plain

 

ちなみに

少しでも変化が生じると、コンパイルボタンに? のアイコンが付きます。

触ったかどうかの確認にもなりますが、変更して元に戻しても、?のアイコンは元に戻ってくれません。

放置していても、エディタ終了時に、Saveしてないけどええのん? というダイアログでビビらせてくるので、強い心で Don’t Save を選択するといいでしょう。不要不急のコミット対象になるのを防ぐためです。

 

 

 

タイトル画面編

次はタイトル画面を用意します。

バックグラウンドと同じ要領でWidgeブループリントを作成します。

アセット名前は wb_Title としました。

f:id:hiyokosabrey:20210516145241p:plain

 

編集していきます。

キャンバスに、TextButton を配置します。

f:id:hiyokosabrey:20210516151300p:plain

階層が必要ないのでまずは適当に置いて大丈夫。

センタリング(中央揃え)したいので、Detailsから設定します。

まずは TextパーツからAnchors の中から 真ん中のアイコンを選びます。

f:id:hiyokosabrey:20210516154011p:plain

この時 Ctrl キーと Shiftキーを押しながらクリックすると数値入力の手間がいくらか省けます。

f:id:hiyokosabrey:20210516155316p:plain

Alignment X を 0.5 にすると、 Position X を 0 にするだけで水平方向は中央に配置できます。

あとは、 高さ(Position Y)と文字サイズ(Font > Size)、表示する文字列(Content > Text)をいい感じに設定します。

背景に合わせてカラーもお好みで。

 

テキストの次は Button も同じようにセンタリングします。

f:id:hiyokosabrey:20210516161217p:plain

中身が無いので、 ButtonText をドロップします。

f:id:hiyokosabrey:20210516161409p:plain

中におさまるとこのようになります。

 

ヒエラルキー上では親子関係になります。

f:id:hiyokosabrey:20210516161600p:plain

Button をフォーカスした状態で、Detailsタブの設定に Slot > Size to Content というのがあるので、ここを有効にすると、うまく収まってくれます。

f:id:hiyokosabrey:20210516161846p:plain

 

f:id:hiyokosabrey:20210516161945p:plain

Size To Content は「中身に合わせるよ」という意味になります。
この状態で、Text の設定を変更します。

f:id:hiyokosabrey:20210516162524p:plain

Padding 設定は 親子構造になると子の側で設定できるようになります。

設定方式が CSS に似ていますが、外側に対して働くイメージなのが、CSSと少しニュアンスの違うところです。

スタートボタンとしていい感じになれば、ひとまず完成とします。

このWidgetコンパイルして保存しておきます。

 

 

出題&回答ボタン画面編

また新たにWidgetを用意します。

アセット名前は wb_Main としました。

f:id:hiyokosabrey:20210516224252p:plain

また同じように必要なパーツを配置していきます。

まず Text を一つ配置。これは出題用のテキストが入ります。

f:id:hiyokosabrey:20210516230359p:plain

問題のテキストが複数行になるのを想定して、サイズを大きめに設定してあります。

文字サイズも読みやすく大きめに。

 

今回背景が明るめなのと、文字の色を黒くしたかったので少し大きめの Image を半透明にして下敷きを置くことにしました。

f:id:hiyokosabrey:20210516231348p:plain

名前を Image_Base に変更しています。

 

UMGでの表示優先(重なり)のコントロールは2種類。

ヒエラルキーでの上下位置 と ZOrder というパラメータです。今回はヒエラルキーで調整します。

f:id:hiyokosabrey:20210516232434p:plain

 

f:id:hiyokosabrey:20210516233619g:plain

後から足した ImageText の下に置かれるので ドラッグして上下を入れ替えるようにするだけでOK。

Photoshop のレイヤーと逆ですね。

 

 

次に Button を用意します。Button には Textも入れておきます。

f:id:hiyokosabrey:20210516233140p:plain

アンカーは左上のままにしておきます。

ここではサイズとPadding の設定にとどめます。

 

ここまではタイトル画面のWidgetと同じ構成になります。

 

さらにこのボタンをまっすぐ並べるための専用パネルを追加します。

Paletteタブの Panel カテゴリにある Vertical Box をドロップします。

f:id:hiyokosabrey:20210516234211p:plain

 

この Vertical Box の子になるように、 先に作った Button を入れます。キャンバスでは操作できないのでヒエラルキー上で親子にします。

f:id:hiyokosabrey:20210516235356g:plain

すると

せっかくサイズ調整したButton が大変なことに!

f:id:hiyokosabrey:20210516235518p:plain

大丈夫です。

まずはヒエラルキー上で Vertical Box を選択します。

f:id:hiyokosabrey:20210517000003p:plain

キャンバス上でマウスを使ってサイズを大きくするか、Details タブからサイズを変更できます。

f:id:hiyokosabrey:20210517000335g:plain

この Vertical Box に入れると、自動で、水平方向にストレッチする仕様になってます。

ちなみに Horizontal Box というのも用意されていて、こちらは垂直方向にストレッチします。

Vertical Box のサイズをざっくり決めたら、アンカーの設定と位置を調整します。

f:id:hiyokosabrey:20210517000638p:plain

高さは大体Button  4 つ分 を想定。

 

適当に拡げたら、中のButtonを選択状態にして

f:id:hiyokosabrey:20210517222841p:plain

Dupulicate(複製)します。右クリックメニューか Ctrl キー 押しながら wキー

f:id:hiyokosabrey:20210517222949p:plain

全部で4つ。

f:id:hiyokosabrey:20210517223655p:plain

 

Button 同士のスキマを開けるには、全部の Button を Shiftキーを押しながら選択状態にして、

f:id:hiyokosabrey:20210517223343p:plain

Detailsタブにある  Slot > Padding の設定で、 Bottom を調整します。

f:id:hiyokosabrey:20210517223849p:plain

 

f:id:hiyokosabrey:20210517224124p:plain

 

 レイアウト完成。

コンパイルして保存します。

 

 

正解演出画面編

つぎに正解した時の演出用画面を作ります。アセット名は wb_Right にしました。

f:id:hiyokosabrey:20210517231717p:plain

 

タイトル画面と全く同じ構成です。テキストが専用なのと、アニメーションがついているくらい。〇は全角文字(日本語の丸)

f:id:hiyokosabrey:20210517231948p:plain

アニメーションは いい感じに。

まずトラックを新しく追加します。

f:id:hiyokosabrey:20210517233529g:plain

IN と名前を付けました。

ヒエラルキーText → アニメーショントラックの IN の順にクリックして、ハイライトしたら、Detailsタブの下の方にある Render Transform > Scale でキーを打ちます。

キーを打つには、数値を調整して下の〇で囲んだボタンをクリックすると打てます。

f:id:hiyokosabrey:20210518000019p:plain

 

調整方法がたくさんあってここ紹介しきれないので、詳しい操作方法については公式のドキュメントをぜひぜひ

docs.unrealengine.com

こんな感じに打ちました。

f:id:hiyokosabrey:20210518000128p:plain

動きはこんな具合。

f:id:hiyokosabrey:20210518000150g:plain


アニメーションができたら、注意しておきたいことがあります。

f:id:hiyokosabrey:20210518003125p:plain

アニメーショントラックにハイライト(フォーカス状態)が残っていると、見た目の表示が、アニメーショントラックが優勢の状態なので、通常時の状態を見失ってしまうことがよくあります。アニメーションをつけるために変更した値が、そのままデフォルト状態になっていることがあって、いざ確認!というときになって あれ? というのがたびたび起こるのがUMGです。今のところ慣れるしかない感じですが、とにかくフォーカスを外して確認 するようにすれば意図しない動きを回避できます。

 

正解演出はこれでいったん完成です。

コンパイルして保存します。

 

 

 

誤答演出画面編

間違えたときの表示です。正解用を複製すると時短できます。

コンテンツブラウザに並んでいるアセットアイコン wb_Right の上で右クリックして、メニューからDuplicate を選択します。

f:id:hiyokosabrey:20210606164004p:plain

 

名前は wb_Wrong にしました。

f:id:hiyokosabrey:20210518010605p:plain

 

パーツの構成は正解演出と同じなので説明は省かせていただきます。

 

〇 を ×(全角の乗算記号)にしています。に変えて、サイズを調整していています。

f:id:hiyokosabrey:20210518224656p:plain



今度はアニメーションを残念な感じにします。

正解は Scaleアニメーション でしたが、Translation(位置) をアニメーションさせます。

f:id:hiyokosabrey:20210518011521g:plain

 

誤答演出もひとまず完成です。

コンパイルして保存します。

 

 

素材はできた。次はいよいよブループリント

ここまでお付き合いくださった方、おつかれさまでした。
《準備編》ということでまだ動きませんが、次回の記事でブループリントを駆使して完成させるとこまでやります。

 レイアウト操作に慣れていれば、30分かからないボリュームだと思います。

UE4のUMGを触り慣れていない方を想定して、比較的細かく操作方法について書いてみたので記事自体は結構なボリュームになってしまいました。次回はどうでしょう・・・

 

 

 つづきはこちら

 

limesode.hatenablog.com