69.拾ったコインの枚数をUIで表示してみよう
前回までの復習
UIを動的(ゲームプレイ中)に変更させる方法は二つある。それが「バインディング」と「IsVariableを有効にする方法」です。
結局バインディングは処理が重めなので、IsVariableが基本的におすすめっていう話をしてきました。バインディングを使わなければならない場面はほぼ無いので、今後のページでもIsVariableで実装していきます。
🐱という訳でIsVariableの方法でコインのUIを実装していきます。
今回実装する機能↓
https://youtu.be/VeHJdPtp0b4
①コインを作る|実践
今回もサードパーソンのテンプレートプロジェクトを使用します。スターターコンテンツを使用するのでプロジェクトに無い方は追加しておきましょう。
https://scrapbox.io/files/65cb441f3f1cb20024465b79.jpg
コンテンツブラウザで右クリック > ブループリントクラス > Actorを選択して名前をBP_Coinにします。
https://scrapbox.io/files/65cb444e14f4730024d6834f.jpg
開いたら追加からCylinder(日本語エディタだとシリンダー)を追加します。
https://scrapbox.io/files/65cb446bf52a390025e0ed8d.jpg
トランスフォームの回転のxを90にして、拡大縮小をxが0.5、yが0.5、zが0.125になるように設定します。
https://scrapbox.io/files/65cb447e506f4900244106a2.jpg
マテリアルを「Gold」と検索してスターターコンテンツのM_Material_Goldを選択します。
https://scrapbox.io/files/65cb4495c24b440024386af4.jpg
追加からSphereCollisionを追加します。
https://scrapbox.io/files/65cb44b7280c120025cd205c.gif
こんな感じになりました↓
https://scrapbox.io/files/65cb44f08120c40024b5d8d0.jpg
🐱すでにコインとなるCylinderコンポーネントにはメッシュのコリジョンがあるので、そのコリジョンを使っても良いのですが球形のコリジョンの方が当たり判定がアイテム中心から均等に広がっているので拾う系のアイテムにはSphereCollisionで当たり判定を行う事がおすすめです。ただどちらでも良いレベルです。
コインのコリジョンはキャラクターと互いに衝突しないようにしたいので、Sphereを選択した状態で詳細 > コリジョン > コリジョンプリセットからOverlapAllを選択します。
https://scrapbox.io/files/65cb4522bc2793002496a415.jpg
これでプレイヤーとなるキャラに対してオーバーラップ(衝突しないがブループリントで検知できる)の当たり判定になりました。
Cylinderコンポーネントのコリジョン>コリジョンプリセットをNoCollisionにして無効化しておきます。
https://scrapbox.io/files/65cb454f928e430025cc99d1.jpg
🐱例外もありますが、基本的に一個のアクタには一個のコリジョンで充分です。必要なくなったコリジョンは無効化しておきましょう。余分なコリジョンは無効化しておかなくても問題になる事はほぼありませんがパフォーマンス的にもシンプルさにおいても、できれば無効化しておいてアクタ一個につき一個のコリジョンの方が良いでしょう。
さらにイベントグラフを開きます。
https://scrapbox.io/files/65cb45d5de253d00240fa19b.jpg
TickからAddAxtorLocalRotationを作成します。Zに1と入力しておきましょう。
https://scrapbox.io/files/65cb484794df9e00247c66b6.jpg
コンパイルします。
ドラッグしてコインをレベルに配置し、複製で増やしておきます。
https://scrapbox.io/files/65cb4867d0597f0025bc99d0.jpg
これでコイン自体は完成です。
https://scrapbox.io/files/65cb488ab8ed220025989909.gif
😺次にこのコインを拾う処理を追加していきましょう。
②キャラクターがコインを拾えるようにする|実践
ではプレイヤーがコインを拾えるように実装します。
ThirdpersonのBlueprintフォルダを開いてBP_Thirdpersoncharacterを開きます。
https://scrapbox.io/files/65cb4be3de7ef800253f00c7.jpg
既存のノードは無視して、CapusuleComponentを右クリック > イベントを追加 > OnComponentBeginOverlapをクリックします。
https://scrapbox.io/files/65cb4c00c24b44002438b4e4.jpg
OnComponentBeginOverlapノードが作成されました↓
https://scrapbox.io/files/65cb4c172d71bb002593019b.jpg
OnComponentBeginOverlapとは?
OnComponentBeginOverlapは他のオーバーラップの設定であるコリジョンに侵入した時に処理を実行するノードです。なのでこのキャラクターがコインのSphereCollisionに侵入した瞬間に処理が実行されます。
Integer型のMyCoinという変数を作っておきます。
https://scrapbox.io/files/65cb4c3bf8ff160025988415.jpg
ではOnComponentBeginOverlapからCastToBP_Coinを作成して、その後に「++」と検索してIncrementIntノードでMyCoinを接続、最後にPrintStringで表示させます。
https://scrapbox.io/files/65cb4c8328fa2b0024b97dff.jpg
IncrementIntノードとは?
Int型の変数に+1して、その変数にセットするノードです。なのでMyCoinが0なら、処理後は1になるという事です。
最後にDestroyActorノードを追加して以下のように接続します。
https://scrapbox.io/files/65cb4cb6ff8ad9002504535b.jpg
作ったノード解説
https://scrapbox.io/files/65cb4ce2c156510024f27f66.jpg
OnComponentBeginOverlapでオーバーラップを検知して、コインだった場合にコインの枚数を+1してセットします。最後にコインを削除します。
一度プレイしてみましょう。コインに触れると消えて、拾うように実装できました。
https://scrapbox.io/files/65cb4d4ef8ff160025988ab8.gif
拾うたびにMyCoinの変数に+1されてPrintStringで表示されます。
https://scrapbox.io/files/65cb4d70a91cbd0027603085.jpg
😺それでは後はコインを拾った時にPrintStringではなくUIのテキストとして表示していきましょう。
③コインのUIを作成し表示させる|実践
では、コインを拾ったらPrintStringではなくこんな感じ↓にUIでテキスト表示してみましょう。
https://scrapbox.io/files/65cb4d908120c40024b62f7d.jpg
ユーザーインターフェース > ウィジェットブループリント > UserWidgetを選択 > 名前をWBP_Coinにします。
https://scrapbox.io/files/65cb4e2e73bfe900246a13eb.jpg
UIフォルダを作成して開いたらCanvasPanelとImageを階層パネルに追加します。
https://scrapbox.io/files/65cb4e43d0597f0025bcc5c8.jpg
今回はこちらのコイン画像を使用します。作ったコインをスクショして背景透過しただけの画像です。こちらをダウンロードしておいてください。
上の画像を使ってください。
https://scrapbox.io/files/65cb4e555f43c000253de029.png
https://scrapbox.io/files/65cec32c2c0c22002564dc6c.png
コンテンツブラウザにダウンロードした画像をドラッグで追加しておきます。名前をCoinにしておきます。
https://scrapbox.io/files/65cb4e6973bfe900246a1633.jpg
WBP_Coinに戻って、Imageを選択した状態で、アピアランス > Brush > Imageからコインの画像を選択します。
https://scrapbox.io/files/65cb4e79b8a18c002415e4e7.jpg
Imageを選択した状態でスロット > サイズXを210,Yを160にします。
https://scrapbox.io/files/65cb4e8d707eb30024827965.jpg
さらにコイン枚数となるTextを追加します。
https://scrapbox.io/files/65cb4e9db7a789002541a023.jpg
テキスト内容となるTextを「0」にして、Font > Sizeを70にします。
https://scrapbox.io/files/65cb4eb0f270db00245c6f61.jpg
Textを選択した状態でSizeToContextにチェックを入れます(緑の枠組みがテキストに合わせられます)。その後テキストの位置を適当に以下の様にコイン画像の隣になるように調整します。
https://scrapbox.io/files/65cb4ed8e5482400250e9800.jpg
大体こんな感じのUIになってればOKです↓
https://scrapbox.io/files/65cb4ef9de7ef800253f2140.jpg
一旦ゲームでUIを表示させてみましょう。BP_ThirdPersonCharacterを開きます。
https://scrapbox.io/files/65cb4f22d9aff80024614b6d.jpg
以下のUIを作成するいつものノードを追加します。CreateWidgetノードからAddtoViewportノードです。CreateWidgetノードのClassにはWBP_Coinをセットします。
https://scrapbox.io/files/65cb4f366aa61a002404e64f.jpg
なぜレベルブループリントにノードを作らなかった?
ちなみにレベルブループリントにこのUIを表示するノードを作っても良かったのですが、プレイヤーにUIを表示するノードを作った理由は単にプレイヤーが保持するコインのUIという事でプレイヤーに実装した方が直感的であると感じたためです。ただここは個人の裁量なので別にレベルブループリントやゲームモードにノードを実装しても構いません。基本的には自身が一番わかりやすい場所にノードを作っていきましょう。
プレイしてみるとこんな感じにUIが表示される事が確認できます。
https://scrapbox.io/files/65cb4d908120c40024b62f7d.jpg
😺後はこのUIを動的に変更させる処理を作っていきます。
④コインを拾った時にUIを変更する|実践
ではこのままだとコインのUIは変化はないのでコインを拾ったら+1されるように実装していきます。
WBP_Coinを開いてTextを選択した状態でIs Variableにチェックを入れます。
https://scrapbox.io/files/65cb4fc4e45845002677dbf5.jpg
これでこのテキストウィジェットを変数化する事ができました。
右上からグラフを開いてブループリントを編集していきます。IsVariableで作成されたTextBlock~という変数がある事が確認できます。
https://scrapbox.io/files/65cb4fe13cd3650024c355b8.jpg
Customと検索してカスタムイベントを追加を選択して、名前をDisplayCoinCountにします。
https://scrapbox.io/files/65cb4ffff209eb00246fed04.gif
その後詳細からインプットのプラスボタン > 名前をPlayerCoin,型をIntegerにします。
https://scrapbox.io/files/65cb5013c156510024f2aa6f.jpg
カスタムイベントとは?なぜ使用する?
カスタムイベントは自分で作れるイベントで、このイベントは好きなタイミングで実行する事ができます。今回はUIのコイン枚数の変化の処理をBP_ThirdpresonCharacter側から呼ぶ必要があったのでこのカスタムイベントを作成して、BP_ThirdpresonCharacterからイベントを発動させます。つまり実行の流れとしては「キャラがコインを拾って変数に+1する→BP_ThirdpresonCharacter側でUIのカスタムイベントを呼ぶ→WBP_Coin側でカスタムイベントが発動→コインのUIが変更される」という順になります。とりあえず実際にやってみましょう。
Is Variableで追加されたTextBlockを追加してそこからsettext(text)と検索してSetText(Text)ノードを作成し、以下の様に繋げます。作るのはSetText(Text)ノードの方になります。
https://scrapbox.io/files/65cb5061db2a850024aef135.jpg
では次にBP_ThirdpersonCharacterのイベントグラフに戻ります。
https://scrapbox.io/files/65cb50818120c40024b649ea.jpg
まず既存のウィジェット作成ノードのAddtoViewportノードへのワイヤーをAlt+クリックで切断します。その後ウィジェット作成ノードのReturunValueを右クリック > 変数に昇格を選択してAddtoViewportノードへ接続します。
https://scrapbox.io/files/65cb50abbc2793002497131b.gif
こんな感じになります↓
https://scrapbox.io/files/65cb50c8280c120025cd7e9e.jpg
作成した変数の名前をWBP_Coinに変更します。
https://scrapbox.io/files/65cb50dede253d002410014c.jpg
🐱これで作成したWBP_CoinのUIを変数へ一旦保存する事ができました。保存する事であとからWBP_Coinのカスタムイベントを呼ぶ事ができます。
次に同じくBP_ThirdpersonCharacterのOnComponentOverlapノードから続くPrintStringノードの部分を修正していきます。
https://scrapbox.io/files/65cb50f823a96c002543d797.jpg
PrintStringノードを削除して代わりに、WBP_Coinの変数をGetで追加して、そこからDisplayCoinCountノードを呼び出します。++ノードからPlayerCoinに接続してMyCoinのデータを渡します。
https://scrapbox.io/files/65cb510f94df9e00247ce079.jpg
🐱これでコインに触れた時に「MyCoinの変数を+1」→「WBP_Coinのカスタムイベントを呼んでコイン枚数のデータも渡す」→「コインのUIが変更される」という流れを作った訳になります。
これでノードは全て完成しました。
完成!プレイしてみよう
プレイしてコインを拾うとUIのコイン枚数が変更されます。
https://youtu.be/VeHJdPtp0b4
BP_ThirdPersonCharacter側でコインを拾ったタイミングでMyCoinという変数に+1して、カスタムイベントを呼んで実行させます。
作成したノードの解説
ではノード解説を少ししていきます。
BP_ThirdPersonCharacter側でコインを拾ったタイミングでMyCoinという変数に+1して、カスタムイベントを呼んで実行させます。
https://scrapbox.io/files/65cb51eb95359c002452a729.jpg
カスタムイベントが呼ばれた時にこのカスタムイベントは実行されます。SetText(Text)ノードのターゲットはIsVariableで変数化したTextウィジェットになっているので、Textウィジェットのテキスト内容が変更されます。
https://scrapbox.io/files/65cb5217ad74030025452eb5.jpg
こんな感じに動的にスコアやコインの枚数をUIで表示していきます。
https://scrapbox.io/files/65cb522d4daa1b0023cc91b3.gif
これで以上になります。
《実践演習》
画像の変更
目標:コインの枚数が10枚を超えたら、コインの画像をandroid Iconに差し替えてみましょう
https://scrapbox.io/files/65cb5d5a33b15a0027fbd250.jpg
・画像の差し替えは『Set Brush From Texture』を使用します