動画の最後に参考資料が紹介されたので
そのまとめ。
◆公式ドキュメント
◆初心者向けUMG講座
◆講談社が用意した資料
◆UMGの応用的な使い方についてまとめている方
◆UEについてまとめている会社
◆実際の使用例
◆プログラマー向けの最適化関連
◆実際にあったumg実装問題と処理負荷対応
それらしい資料が出なかったのでカット
これにて第七回講座終了。
長かった…
Q&Aコーナーで扱われていた、
コインを取得時の徐々にスコアが上がっていく演出を作る。
まず、コイン取得時のスコアを「+10」に変更する。
「++」を「+」ノードに変更し、
10点加算されるようにする。
更にUI側でカウントアップする仕組みを作る。
まず、更新したScoreの値をSetScoreでGoalScoreに代入して、
そこまでカウントアップさせる。
CurrentScore(過程の値)とGoalScore(目標の値)が一致しない場合、
CurrentScoreに「+1」する処理を行い、
それをToTextでUIにセットして反映する。
これでスコアがカウントアップされる仕組みが完成する。
おしゃれでかっこいい。
ちなみに、今のままだとTickのテンポで毎フレームカウントアップするが、
カウントアップ速度を調整するために
Set Timer by Eventによってイベントの発生頻度を時間で指定することができる。
フレーム数だと安定しないこともあるため、
時間制御の方がいいかもしれない。
これでテンポがよくなった。
他にも細かい要素の紹介をしているが、
ちょっと数が多いのでカットして次へ行く。
Q&Aで触れられていた、
スコア増加エリアの内容をまとめる。
<触れているとスコアが増加するエリアを作る>
BPクラス>Actorを作成
で新規Actorを作成し
BP_ScoreAddAreaと命名。
ビューポートから
・コンポーネントを追加>Box Collider を追加
・コンポーネントを追加>球 を追加
して、領域を作成。
形状は、球を薄く引き伸ばして用意する。
作成したActorをレベル上に配置して、
サイズをいい感じに調整する。
次にAreaにOverlapしている時の処理を作成する。
Sequenceを使うことで、既存の処理を残しつつ、
新たな処理へつなぎこむことができるので、既存の処理の間に追加。
そして、Cast To BP_ScoreAddAreaノードを追加し、
bool型変数「今エリアにいるよ」を作成・追加する。
これにより、プレイヤーがオブジェクトに接触した時、
「今エリアにいるよ」がTrueになる。
イベントActorEndOverlapでエリアを出た時に
「今エリアにいるよ」をFalseにする処理も忘れずに追加しておく。
「Key1を押下した」&「今エリアにいるよ」がTrueの時に
Scoreの値に+1した値をSetScoreで更新する。
これで、「回復エリア上で1キーを押すとスコアが1増える」機能が追加された。
ちなみに、Castを使うとゲームが重くなることがあるらしい。
プロは使わないほうがいい、とのこと。
これについての補足は後の講座で説明があるらしい。
<補足>
スコアを0で埋める。
以下のように、ToTextのDigitを設定することで
桁数を事前に0で埋めておくことができる。
参考ではDigitが3なので、3桁表示になるというわけだ。
<エリアに入ると「クリアー」と表示されるようにする>
さっき作成したAreaを使って、
触れたらクリアーが表示するようにする。
まず、UIからWidgetBPを作成し、
「クリアー!」のtextだけを配置する。
次に、先ほどのAddScoreAreaに接触した時のセット処理に
「ウィジェットの作成」を追加し、
先ほどの「クリアー!」を用意したBPクラスを指定。
AddToViewportで画面に表示する仕組みを追加する。
これで、Areaに触れた時に「クリアー!」が表示されるようになる。
実際にコインを獲得した際に、スコアを変動するようにする。
まず、UIの数値部分だけを変動させるために
「スコア:」「2(数値)」という形にテキストを分割する。
今後は「2」の部分だけが操作されるというわけだ。
この数字部分の変更方法だが、
やり方の一つに「バインド」というものがある。
コンテンツ>Textの右部分にある「バインド」をクリックして
「バインディングを作成」を選び、そこからBPの関数で数値を操作するというものだ。
バインディングを作成すると、リターンノードという
BPが現れるので、
そこに新たに変数をつなぎこむ。(今回は「Score Text」と命名)
この変数がスコア値となって、
今後反映されていく。
講座中では、ひとまず開始時に変数に4をセットして
変化を確かめた。
これだけだとスコアが随時反映されないので、
スコアが変動するようにしてあげる必要ある。
なので以下のように組みなおす。
この形にすることで、
「Set Score」を経由してスコアが変動できるようになった。
※Set Scoreはint型にしておく。ToTextを経由することで
文字列に変化する
UMG側の実装は以上となる
<プレイヤー側でスコアを計算する>
コインの獲得はプレイヤー側で判定を管理する。
ThirdPersonCharacterのBPを開き、
に「Action Begn Overlap]で重なった瞬間に
「Cast」ノードで対象を指定することで
特定の種類の接触判定を取ることができる。
上記の内容はあくまで判定したかどうかを見ているだけなため、
更に以下のように変更し、Scoreの内容に接触するたびに+1加算する
仕組みとなる。
※PrintStringは検証用
次に、変数を実際にウィジェットに反映できるようにする。
以下のように「Return Value」からノードを伸ばし、
変数「UI」を追加する。Add to Viewportのノードもつなぎこむ。
(「Return Value」は「Add to Viewport」と「UI」のどちらにもつながっている)
さらに、スコア側にも新たに「Set Score」を用意。
スコアとして表示していた内容を
Set Scoreによて実際に「UI」に反映させる。
これで完成。
※そのまま講座通りに進んでいると、初期値が適当な数値になっている可能性があるので
修正する
※1ずつ加算ではないようにしたい場合「++」の部分を適当な加算処理に変える
▼完成後はこんな感じ
(画面がごちゃごちゃしている…)
同じように値を取得することで、
HPの表示や「Game Over」といった表示の管理も行えるようだ。
実際にUIを画面上に出していきます。
今回はキャラクターに紐づける形で作る。
まずは、必要な情報を表示したwidgetを用意。
続いて、
自身のキャラクターをクリックして
アウトライナのThirdPersonCharacterを選択。
項目右部の下線が引かれているリンクからBPを開く。
開いたキャラクターのBPで
イベントBeginPlayからノードを伸ばし
新規ウィジェットのクラスには、先ほど用意しておいた
表示したいwidgetを設定します。
それだけだと「画面に表示する」という処理がなされていないため、
「Add to Viewport」で画面上に表示を行う。
※ちなみに動画中では、別の手法としてAdd to Player Screenを紹介していた。
Add to Viewportでうまくいかない場合は使うといいんじゃない?、
という程度の説明だったが…
プレーヤー専用のセクションで、ウィジェットをゲームのビューポートに追加します。
これは、ビューポートのプレーヤーの部分にのみウィジェットを表示する必要がある
分割画面ゲームで役立ちます。
とのこと。
など、複数人が1画面で遊ぶゲームで使うんだろう。
◆UIのアンカー設定
画面の比率が変わった時に、アンカーを設定していないと
UIの位置が崩れてしまう。
アンカーはスロットから設定することができるので
基本的にやっておいた方がお得。
という感じで、UIの画面表示が行えた。
次回は実際に値が変動するようにする。
---
おまけ
WidgetComponentを使うことで
3D空間上にUIを置くことができる。
方法はシンプルで
・Actorをフィールドに配置
・該当のActorの詳細から「コンポーネントを追加」しWidgetを追加する
・詳細からWidgetClassから表示したいWidgetを選択する
で画面上に表示される。
後は回転角度を調整してやれば
フィールド上に配置できる。
この時、Widget > ユーザーインターフェース > Space
がWorld になっているが Screen にすることで常に画面に向いた
HPバーを出したりできるのだ。
UMGの埋め込みについて学んでいく
◆ウィジェットを配置して、UIを表示する
ウィジェットの機能を使って、いろいろUIを配置してみる。
使ったUIは以下の通り
・Text…「UnrealEngineサイコー!」と表示している部分。
文字色を変えたり、影を付けたり、フォントを変えたりする。
・Image…Androidっぽいアイコンを表示している部分。UIの画像を配置できる
・ProgressBar…Androidっぽいアイコンの下にあるエネルギーバー
・Button…長方形のブロックのような部分
・CheckBox…長方形の右にあるブロック。クリックすることでチェック状態にできる
基本サイズは小さいので、ImageSizeを変えることで大きくしている
・Slider…長方形下にある棒状のUI。つまみを動かして操作をするメニュー
・CircularThrobber…ぐるぐる回るローディングっぽい演出
・ComboBox...プルダウンで項目を選ぶメニューUI。詳細は以下を参考
また、パーツ同士は重ね合わせることが可能。
Button上にTextを配置することで、文字を表示したりできる。
次回は、これらUIに対して
グラフでふるまいを設定していく。
生成した弾のエフェクトをよく見ると
弾が消えるとトレイルもぱつっと消えてしまっており
やや見栄えがよろしくない。
それを解消しようというQ&Aだ。
◆Bulletとエフェクトを切り離す
トレイルが消えてしまうのは、Bulletにパーティクルが紐づいているため、
Bulletが消えると一緒に消えてしまうのが問題なわけだ。
そこで
Detach From Component
をEndPlayと消滅パーティクルSpawnの間に挟むことで
弾とトレイルのエフェクトを分離することができる。
ターゲットにはParticleSystemをドラック&ドロップしてgetする。
この時、デタッチの各要素の扱いをどうするか?の設定を行う。
・Keep Relative...相対を維持する
・Keep World...絶対座標を維持する
今回は、消失した時の座標で止まってほしいのでKeep Worldを設定。
◆DestroyActorをやめて各要素をオフにしていく
DestroyActorをやめて、
・Set VisbilityでSphre(弾)の可視状態をオフに
・Set Collision EnabledでBox(接触判定)をオフに
・Set ActiveでProjectile Movement(弾自体の挙動)をオフに
として各要素をオフにする形で対処していく。
(これでオブジェクトは残り続けないのか気になったが、
時間経過で消えるので大丈夫そう…?)
これでトレイルがきれいに軌跡を残して消えるようになる。
ただし、場合によってはエフェクトの先端が残ってしまう。
動画中ではエフェクトデータから直接、