みつまめ杏仁

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

そうだ、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

 

 

 

 

 

 

 

雑記#20210417

今年も新人さんたちが入社してきました。去年のこの時期はいろいろとアレやコレやでもう大変でしたが、新型コロナに気を取られてもう一年が経ちました。早いものですね。まだまだ脅威は去っていないというかむしろ近づいてきてる気がするので、戦々恐々とする毎日です。UE4でもいじって心を落ち着かせるとしましょうか。小ネタですがブログに残しておきます。

 

 

 

最近Twitterにあげたやつ その1

あの最近話題の育成ゲームです。ついアニメも観てしまい、涙腺対応でティッシュの山を築きながら作りました。

最初『春のゲージ祭り』というお題で記事を書こうと思っていろいろ準備していたら、いつの間にか体力ゲージができていました。マテリアルを使ったゲージで、なるべくパーツ数を抑えていろいろ表現できないかと模索しているところだったので、さっそく参考にさせてもらうことにしました。

マテリアルでいろいろやりすぎるとGPUの負荷が心配にはなりますが、ゲージなので面積は大きくはないし、表示するパーツ数を増やさず情報量を増やすことができるので、結果的にオートレイアウト的な処理が減ります。もちろん実機で負荷検証するのは必須なんだけど、よいこは真似してみてね。

 

マテリアルはこんな感じ

f:id:hiyokosabrey:20210416005711p:plain

予想値 現在値 をそれぞれ Step で 0 と 1 に分けたものに、0.8 と 0.2 をかけてます。

f:id:hiyokosabrey:20210416013016p:plain

f:id:hiyokosabrey:20210416012444p:plain

足し算して 1.0 になればOK。

これを Lerp ノード に渡すと、濃淡が表現できます。

f:id:hiyokosabrey:20210416211158p:plain

1.0 のところは、グラデーションがそのままで、 0.0 のところは ベースのカラーが、 0.2 のところは線形補間(Linear Interporate)された状態になります。

f:id:hiyokosabrey:20210416013441p:plain

これで、特訓によって減少するであろう未来が表現できた。

 

次は増加するときの見た目。

加算と減算で条件分岐、とかやりたくなかったので、

f:id:hiyokosabrey:20210416212421p:plain

予想値 と 現在値 の差分を 計算に利用します。

f:id:hiyokosabrey:20210416213413p:plain

これをゲージ本体のカラー(グラデーション)の底上げに使います。

f:id:hiyokosabrey:20210416214133p:plain

加算するといい感じになるように底上げ具合を調節。

f:id:hiyokosabrey:20210416214412p:plain

 

予想値が下回った場合は減算になります。

f:id:hiyokosabrey:20210416214813p:plain

マイナス値をどうにかしないと、ということで登場するのが clampノード。

clampノードは 指定した範囲をオーバーした値はカットします。

正確には、 Min を超えれば Min の値、 Max を超えれば Max の値になります。ノードのデフォルトが Min = 0、 Max = 1.0 なので何もつないでませんが、ゼロ以下の値が入ってくると、しれっと 0.0 を返します。

f:id:hiyokosabrey:20210416215447p:plain

回復分のカラーに 常にこのclamp後の値を掛けてるので、加算のとき、減算のときで、2種類の状態を作り出せます。

 

掛け算と足し算だけでもこういった条件分岐みたいなことができるので、面白いですね。

掛け算のこの3つパターンを押さえておくとイイことあるかもよ。

0 × 0 = 0

0 × 1 = 0

1 × 1 = 1

掛け算に ゼロ が入ると問答無用で ゼロになります。

また、イチ を掛けると何も変化しません。

この辺をうまく組み合わせて作っていきます。もし触るのをためらっているUIデザイナーがいらっしゃるなら、UI表現の幅も広がるので、恐れずにぜひいろいろ試してほしいです。

 

せっかくなんで増減するアニメーションを作ってみました。

f:id:hiyokosabrey:20210416221115g:plain

 

ブループリントでは、ゲージのImageにセットしたマテリアルを、Dynamic Materia lInstance として変数化しておきます。これを使ってマテリアルにアクセスします。

f:id:hiyokosabrey:20210416221620p:plain

予想値をもらって反映するイベント(または関数)も用意。

 

マテリアルのパラメータをセットする関数はこんな感じ。

f:id:hiyokosabrey:20210416221803p:plain

今回 Float型の変数は3つ使ってます。

f:id:hiyokosabrey:20210416222257p:plain

 

増減のアニメーションは Set Timer by Eventノードで。

f:id:hiyokosabrey:20210416222031p:plain

 

やりたい仕様がうまくできるとパズルが完成したような心持ちがします。

と思いつつも、ゲームをプレイしながら増減するときの動きをよくよく観察していると、重ねて処理しているように見えるので、今回のつくりは完コピにはならなかったけど、いろいろ検証できたので面白かった。

 

 

 

 

 

最近Twitterにあげたやつ その2

 

ふと思いついて試してみたシリーズ。

この 〇れ味ゲージは過去記事でやってまして、当時はマテリアルを使いました。

limesode.hatenablog.com結構ややこしいことしてましたね。

 

 今回は HorizontalBox を使います。マテリアルは一切使用しません。とてもシンプルです。

f:id:hiyokosabrey:20210416224826p:plain


HorizontalBoxをひとつ、子供として色のついた Image を入れます。

f:id:hiyokosabrey:20210416225020p:plain

HorizontalBoxの子になると、親のタイプに合わせて Slot が変化します。

f:id:hiyokosabrey:20210416225850p:plain

Size の値を変更すると、幅が変わります。

すべての Sizeを 1.0 にすると、すべてが等幅な状態になります。

ぴっちりと隙間なく自動で調整してくれるので、個別にSizeをいじってやれば棒グラフ完成です。

可変しなくて固定の棒グラフならこれを量産して、表示を切り替えるだけで使えそうです。でもやっぱりスクリプトから制御したいですよね。というわけで・・・

 

まずは、Size を適用する関数。

f:id:hiyokosabrey:20210416231416p:plain

Get Child At ノードは、 HorozontalBox の 子要素を、Index番号でアクセスできるようにするノードです。

下の Make系 ノードは単体で検索するより、この場合、右上の Set Size ノードの左のピン In Size からドラッグするとすぐ近くに見つかります。

f:id:hiyokosabrey:20210416231928p:plain

 

Float型の配列を一つ作って、適当な値(テスト用)を入れます。

配列の数は HorizontalBox の Image と同じ数。

f:id:hiyokosabrey:20210416232657p:plain

 

これを計算して比率を求め、上の関数で適用します。

いったん全部足して最大値を求め、それで割ることで一つ一つの割合がわかります。

f:id:hiyokosabrey:20210416232834p:plain

LastIndexの値は一応 引数として受け取れるようにしてます。
テストだったら固定値を入れたつくりでも問題ないですが、こうしておくことで、一度できたこの関数を編集する機会が減らせます。結果調整の手数が減ります。

 

グラフの表示を更新するイベント(または関数)

f:id:hiyokosabrey:20210416235045p:plain

ゲージ全体の長さは 0~1.0 で受け取る仕様。500は実際に表示する最大の長さ。

ゲージの長さを実際の表示幅で受け取る仕様だと、デザインやレイアウトの変更でゲージそのものの長さを変更する際に大きな問題となります。パラメータを管理する者と、デザインを管理する者はおそらく別々だろうと思うので、なおさらこういった配慮はメンテナンスのコストを下げる効果があります。

 

f:id:hiyokosabrey:20210417000108p:plain

できあがり。

 

グラデーションのテクスチャ作って Image にセットすると見た目を少しアレンジできます。

f:id:hiyokosabrey:20210417114830p:plain

f:id:hiyokosabrey:20210417114725p:plain

 

 

 

 

文字でも世界観を

遊んでいて最近気づいた。

f:id:hiyokosabrey:20210417011037p:plain

 基本的に『馬』の表記を「ウマ」「バ」と回避しつつも、「有馬記念」だけはどうしようもなかったんだろうな。『有マ記念』・・・『アリマ記念』

 で、結果フォントのグリフいじってるようですね。たった一文字、この一文字を加工するだけで、このフィクションな世界のリアリティを感じさせてくれる心遣いがステキすぎる。

 外字として追加するのが簡単だしコストが一番安くできるんだけど、置換が必要になるうえ、テキスト管理のコストや置換漏れの確認工数なんかがパないので、おそらく馬(U+99AC)のグリフそのものをいじる方が安全ということだろうと思われる。自分だったら確実にそう提案する。TextMeshPro(埋め込まずにAtlasを使用する方)使ってるんだったらマージしてるかもしれない・・・?

 フォントベンダーの名前が見つけられなかったんだけど、オリジナルフォントじゃなければそれなりにコストと期間は支払っているはずで、それでもやってやろうという開発スタッフの愛と意気込みに感服です。さすがに馬偏の漢字はいじってないみたい。

 

 

ではでは

今回はこの辺で

誰かの何かに役に立てれば幸いです

 

 

9スライスを試してみたメモ

ダイアログウィンドウなんかのサイズが可変するウィンドウでよく見かけるUI表示で、制作環境によって呼び名が変わるようです。9スライスとか、9-patch とかいうやつ。

UE4でももちろん標準実装されているのでとても手軽に使えます。

詳しくはこちらの記事。

historia.co.jp

普通に使えるのに、わざわざマテリアルで試そうと思ったのは、カラーを乗せたかったから。

で、できたのがこれ。

 

 

f:id:hiyokosabrey:20210404135055p:plain

AlphaチャンネルとRGBカラーを分離すれば実現できるはず。ということでマテリアルと格闘することになったのでした。

 

UE4の Mergin指定はデザインに対して柔軟に合わせられるつくりなので、真似してみたかったけど、まずはシンプルなところから理解していこうということにしました。

今回は作り方というより考え方の記録みたいな内容です。

 

下図は、UMGでの指定方法。

f:id:hiyokosabrey:20210404152543p:plain

考えやすいように、Marginは 0.5 固定で進めます。

Marginはテクスチャの分割位置を上下左右の端から割合で指定するので、全部 0.5 ということは中央になります。

 

用意したテクスチャ ↓

f:id:hiyokosabrey:20210404144830p:plain

 

実際に描画する際は、この4分割のパーツを9か所に配置することになります。

f:id:hiyokosabrey:20210404152307p:plain

縦と横の中央部が延ばされます。

 

マテリアルでこのようなUVを作れればOKなわけです。

f:id:hiyokosabrey:20210404153913p:plain

 

まずは U方向(水平)について考えてみます。

 

変化量を縦軸にしてグラフにすると下図のようなイメージになります。

f:id:hiyokosabrey:20210404160306p:plain

何も手を加えなければ、0 ~ 1.0 へのまっすぐな直線です。これを指定したSize固定部分で分断して引き延ばす感じ。

 

ノードで組んでみるとこうなりました。

f:id:hiyokosabrey:20210404161037p:plain

Scalarパラメータノードが Size固定部分の値になります。

そこを if ノードで判定して、ナナメ(0→0.5 と 0.5→1.0 )にするか、0.5 にするかを仕分けています。

もっと頭のいい計算方法があると思う。

パッと見ややこしいし、U方向だけでこのボリューム感。ついでにSize固定幅の指定をピクセルで指定したいので、TexCoord[3] を活用。

これについてはこちらのツイートが参考になりました。

 

コピペとはいえ V方向のぶんも必要なので最終的にこうなりました。

f:id:hiyokosabrey:20210404162522p:plain

 

コンパクトにしたいので、HLSLのコードを書ける Customノードを試してみました。

f:id:hiyokosabrey:20210404164709p:plain


 1 |  float temp = 0.5 / Width;
 2 |  float result;
 3 |  if ( Value < Width ){
 4 |    result = temp * Value;
 5 |  }else {
 6 |    if ( (1 - Width) < Value ) {
 7 |      result = (Value -(1 - Width)) * temp + 0.5;
 8 |    }else {
 9 |      result = 0.5;
10|    }
11|  }
12|  return result;

 

すっきり。

f:id:hiyokosabrey:20210404174746p:plain

 

今回 ノードで組むより、コードで書いたほうが Instructions(命令)数は少なくなった。

f:id:hiyokosabrey:20210404175137p:plain

 

使ったテクスチャはこれ。

f:id:hiyokosabrey:20210404200330p:plain

 

できたマテリアルは、いつも通り Image に貼り付けて完成。

f:id:hiyokosabrey:20210404193556g:plain

 

これで途中で伸びることなくカラーテクスチャが自由にオーバーレイできるようになった。

f:id:hiyokosabrey:20210404195354p:plain

UVの計算方法については、結果オーライでまったく自信ないので、どなたか頭のいい人ご指摘いただけるとありがたいです。

 

テクスチャの品質で圧縮による劣化を少しでもマシにしたくて、RGB と Alphaを別々の解像度で作って合体させるというのを実践しているのですが、今回のネタもそこからのつながりです。

まだまだ、応用できそうですが今回はこのへんで

 

 

ではでは

すてきな9スライス ライフを!

 

 

 

レーダーチャート作ってみた

 

f:id:hiyokosabrey:20210327154555j:plain

いやぁレーダーチャートですよ。ゲームのUI作ってると、避けて通るのが難しいというか、ヘタに避けると事故るというか、かといって簡単には実装させてくれないというツンなところが憎いレーダーチャート。ステータス画面でキャラの成長度合いや武装なんかの性能差をパラメータ表示する際に使われることが多い印象。

ポリゴンメッシュのような柔軟な形状変化は、半透明テクスチャベースでの2D表現ではほぼ無理(直線の組み合わせなので頑張ればできますが、なり力技で無駄なパーツも増える)だし、プログラマさんへの負担がかなり高いのもレーダーチャートです。なのでプログラマさんの顔色伺いながらデザイン提案してきました。

かねてからレーダーチャートを自力で作ってみたくて、思いついたアイデアを実践してみたのが今回つぶやいたやつです。

たまたま思ってた感じに動作してくれたので、メモしておきます。

三角関数とかベクトルとかそういった計算は一切使ってません。

主に掛け算と引き算です。

さすがに こんな変則的な作り方が採用されることはないと思いますが、参考になれば幸いです。

 

 

blenderでメッシュを用意する

Verは 2.92 です。大したことしないので旧いVerでも他のDCCツールでも問題ないです。まず円錐を作ります。6角錐でも5角錐でもOK。底面は不要。

スケール をゼロにしてぺちゃんこにつぶしたら、スケールを「適用」して 1.0 に戻す。

[ObjectMode] モード Object → Apply → Scale

f:id:hiyokosabrey:20210327155834p:plain

この時 底面が残っていると、ポリゴンが重なってしまって作業しづらくなる。

(ぼくはこの後 X軸を 90度回して Apply します。)

 

[Vertex Paint] モードにして 頂点カラーをつける。

f:id:hiyokosabrey:20210327161029p:plain

このとき 中途半端な値にならないようにしっかり塗る

色の順番は法則とかないので適当でも大丈夫。

ただし中央は動かないので 黒(0,0,0)または白(1,1,1)推奨。

 

色がついたら、FBXで書き出し。

(今回 FBXのバージョンとかはデフォルト設定のまま)

正面方向と上方向の軸に注意。インポートしてみて向きがおかしかったらモデルを回転させるか、FBXの書き出しで対応するかどちらかで。この辺は、作業のやりやすさと、エンジンにインポート後の配置のしやすさを考慮すると自然と決まってくる。はず。

 

UE4でのインポート時のダイアログで、

Vertex Color Import Option を  Replace に変更する。

f:id:hiyokosabrey:20210328004351p:plain

マテリアルの設定は

探さない、作らない、読み込ませない の3無い運動で。

f:id:hiyokosabrey:20210327163013p:plain

 

無事インポートできら材料は揃ったので、次はマテリアルをどうにかすればほぼ完成。

 

新しくマテリアルを作成したら、

ShadingModel は Unlit(光源計算なし)を選択。

まず VertexColor をつなぎます。

f:id:hiyokosabrey:20210328005311p:plain

 

プレビュー用のメッシュを登録すると作業がはかどります。

f:id:hiyokosabrey:20210328005030p:plain

 

 

できあがった全体図

f:id:hiyokosabrey:20210327165548p:plain

 

まずは頂点カラーを取り出すところ

f:id:hiyokosabrey:20210327165717p:plain

各頂点のカラーから、ある数字を取り出すのにカスタムノードを使用。

中身こんな状態。

f:id:hiyokosabrey:20210327170021p:plain

Codeのところは

return float((Red * 4) + (Green * 2) + Blue);

Red, Green, Blue は下の Inputsのところで設定した名前。

 

何をやっているかというと、

RGB を 111 の 2進数と見立てて 0~7 の 10進数 に換算してる。

f:id:hiyokosabrey:20210327171446p:plain

 

これで、各頂点に番号を振ったのも同然。

あとは、個々でパラメータを反映してやるだけ。

 

blender のVertexPaint は デフォルトだとアルファが使えないので、今回のやり方だとRGBの3つしか使えないけど、アドオンでアルファを使えるようにしたら、ARGBの 4つが使えるので、最大15個の頂点を制御できると思う。試してないけど。

 

あとは、この 1 ~ 6 の値を if ノードで判定しながら頂点を動かします。

f:id:hiyokosabrey:20210327221544p:plain

LocalPositionノードは、メッシュが持つ頂点の位置で、メッシュの中央からの座標になります。

上の図の場合、VertexColor が RGB(0,1,1) のとき(= 3) という値が来たときだけ、 ScalarParameter(上図のRightUpper)を流して、それ以外は 0 を流します。

マテリアルが受け取る値は 0 ~ 1

f:id:hiyokosabrey:20210327223033p:plain

0 のときMAXなんで、 気持ち悪ければ OneMinus ノード使ってもいいのですが、計算が増えるので処理負荷を考えてここは受け入れています。

各頂点は、Meshの原点から離れた位置にいます。ここに掛け算することで、方向を保ったまま、原点に近づいたり離れたりするわけです。

で、この掛け算した結果を、元の頂点位置から引き算することで結果的に凹みます。

用意したMesh が最大値の状態なので、こういった発想に至りました。

 

あとは連鎖的に、次々各頂点の計算をして引いていきます。

f:id:hiyokosabrey:20210327224400p:plain

もう少し違うやり方もありそうな気がします。

  

中央以外の頂点を計算し終えたら仕上げ。

f:id:hiyokosabrey:20210327224649p:plain

TransformPosition に渡して、そこから AbsoluteWorldPosition を 引いてようやく 出力できます。すでに存在するメッシュに対して、部分的に頂点を動かしたら、この計算しておくことで、相対的な動きになります。

Lerp ノードのところは、頂点カラーを確認するためのものなので、以下の形で問題ないです。

f:id:hiyokosabrey:20210327230809p:plain

マテリアルは完成です。

 

新しく Actorブループリントを用意して、StaticMesh を  AddComponent します。

そこに インポートしたメッシュと出来立てのマテリアルをセット。

 

f:id:hiyokosabrey:20210327231943j:plain

 

メッシュのマテリアルをいじるには、Dynamic Material Instanceを用意します。

 

f:id:hiyokosabrey:20210327232814p:plain


Targetにつながった StaticMesh は、 Viewportで追加したやつ。左のリストからドラッグ&ドロップ。

Source Material のところに 今回用意したマテリアルをセット。あとはReturnValue ピンから 変数に昇格(Promote to Variable)させておきます。

 

パラメータを管理するための配列を用意します。

f:id:hiyokosabrey:20210327233722p:plain

 

配列の中身を個別に取り出す関数

f:id:hiyokosabrey:20210327233833p:plain

Pure型にするのをオススメ

 

そして、この配列の中身を一気にマテリアルに反映するのがカスタムイベント。

f:id:hiyokosabrey:20210327234239p:plain

下のほう見切れてるけど、同じような形なので省略。

マテリアルパラメータ名と、配列変数の Index が合ってさえいれば問題なし。

 

ひとまずこれで必要なものは全て揃いました。

 

あとは配列の中身を書き換えて、カスタムイベントを呼ぶ。

これだけです。

 

Twitterにあげた動画は、ランダムにパラメータ書き換えて遷移するように特別に組みました。

エンジンの操作(オペレーション)についてはかなり省いているので、わかりにくかったらごめんなさい。謎なところなどあればコメントいただけると補間します。

 

正7角形までだけど、 頂点の数が変わっても簡単に対応できます。

使用できるカラーは以下の8色。

f:id:hiyokosabrey:20210328001003p:plain

RGBの各輝度は 1.0 = 255 です。実は blender のRGBの扱い方が 0~1.0 なのです。

f:id:hiyokosabrey:20210328001334p:plain

将来的に、HDR時代が当たり前になったら、255 とか FF みたいなこと言うと年寄り扱いされるかもしれないので今から慣れておくといいかも。

 

円錐の角数を変えてたので試してみた。マテリアルは使いまわし。

f:id:hiyokosabrey:20210328011746j:plain

ブループリント複製して、StaticMeshの中身差し替えて、減った頂点のぶん不要な処理を削っただけです。

 

ひとまずここまで作れて満足してます。

UE4は普通にメッシュ描けるので、ぶっちゃけこの方法は必要ないと思います。

頂点カラーで特定の頂点を動かすことができるのに気づけたのはよかった。

 

Widgetでシェイプが扱えるようになるといいな。

 

ではでは

すてきなレーダーチャートライフを!