まばたきのポストプロセスマテリアル
タイトル通りです。
概要
以下のような、ホラゲー導入シーンでありがちなまばたきのマテリアル(Eye blink material)を作りました。
調べても、メッシュを動かして作る方法など、私がやりたかったものとは異なる実装しか見つからなかったので自前で組みました。
なお今回は、シーケンサーでパラメーターを変更する都合上、Material Parameter Collectionを用いましたが、勿論Scalar ParameterでもOKです。
作り方
新規マテリアルの作成
コンテンツブラウザ右クリック>「マテリアル」>「マテリアル」で新規マテリアルを作成します。
ポストプロセスとして使うので、作成したマテリアルの編集画面にて、下図のようにマテリアルを設定します。
マテリアルの組み方
細かい説明は無しで、作り方を淡々と説明します。
全体像は下図の通り。
マスク部分の中身は下図の通り。Blink Valueというパラメータは、まばたきの度合いを0~1で指定する部分です。冒頭で述べた通り、Scalar ParameterでもOKです。
また、SmoothStepではなくStepのほうを使えば、ぼんやりとしたまばたきではなく、カチっとしたまばたきにできます。
PostProcessInput0に対して、作成したマスクを使って黒色(瞼に覆われている部分の色)で補間します。
…以上。お役に立てば幸いです。
UIマテリアルでテキストなどをおもしろくする
この記事は、Unreal Engine (UE) Advent Calendar 2023の20日目の記事となります。
はじめに
今回は、UE5のウィジェットで、テキストにエフェクトを加えたり、UIの部分的または全体にポストプロセス的にエフェクトを加えたりする方法を紹介します。
※使用したUEのバージョン:5.3
フォントマテリアル
UE5のUIを作る際に使用するウィジェットには、フォントマテリアル(Font Material)というものがあります。これは、UTextコンポーネントなどで使用できます。テキストにアウトラインを付けたりするのは、フォントマテリアルを使わなくてもできるようになっておりますが、テキストにテクスチャを適用したり、変形したりといったちょっとしたエフェクト的なものを与えたい場合には、フォントマテリアルを使用することになります。
例)アウトラインにフォントマテリアルを割り当ててオーラ的な動きをつけたもの
フォントマテリアルの準備と適用方法
1)新規マテリアルを作成し、Material DomainをUserInterfaceにします。
Blend Modeは通常のマテリアルと同様にOpaqueやMasked, Translucentなどが使え、出力が異なります。文字の一部を削りたいなどの場合はMaskedを使う必要があります。
↓通常のマテリアルとは出力が異なる(Blend Mode = Translucentにしたもの)
2)次に適用方法ですが、ウィジェットにText,Editable Text,Rich Text Blockなどを配置して、詳細パネルから割り当てます。なお、テキスト本体および輪郭のフォントマテリアルは分かれており、それぞれにマテリアルを割り当てられるようになっています。
Textureで柄を付ける
基本
以下のようにVertex Color(テキストカラー)にUEロゴのテクスチャを乗算したものを最終カラーに出力してみます。
ウィジェットのテキストの詳細パネルには上記画像のように、テキストの色と透明度を設定する項目Color and Opacityがありますが、ここで設定した値がフォントマテリアルのVertex Colorとして使用されます。
[結果]
テキストカラーは白にしているので、UEロゴのテクスチャがそのまま乗りました。
文字ごとにテクスチャで柄を付ける
先ほどの例では、テクスチャがテキスト全体に収まるようにストレッチがかかっていましたが、文字ごとにテクスチャの柄を付けたい場合には、どのようにすべきでしょうか。Texture SampleにTex Coordを入力してみます。Indexを「1」にすることで、文字ごとの座標が取得できるようです。
[結果]
各文字に対してテクスチャの柄が付けられました。
スクリーン空間にテクスチャで柄を付ける
先ほどまでの例ではすべて、テクスチャにストレッチがかかってしまっています。これの回避策としては、ScreenAlignedPixelToPixelUVsを使う方法がありますが、名前の通りスクリーン空間にテクスチャが貼られるような形になるため、パターン柄でない限りは使いづらい方法です。
[結果]
テキストの位置が変わっても、テクスチャの位置は変わりません。
テキストを動かす・変形する
テキスト位置をテキストカラーによって動かせるようにしてみる
マテリアルの出力にあるスクリーン位置に入力を与えることでテキストを動かしたり、変形したりできます。
試しに以下のようなマテリアルを組んでみました。
画像のコメントにある通り、テキストの色が変わるとスクリーン位置も変わると予想できます。
[結果]
予想通り、テキストの色によって位置が変わりました。
テキストを変形させる
テキストを変形させるマテリアルを適当に組みました。
[結果]
ふにふに動きます。ただし、四隅しか動かせません。
↓動きを横方向に制限したもの
エフェクトマテリアル
フォントマテリアルでは、テキストにエフェクトを与えられますが、RetainerBoxのEffect Materialを使うとUIの部分的または全体にポストプロセス的な加工をできます。これはおもしろくて、今回紹介する基本的なもの以外にもいろいろな活用方法があると思います。
エフェクトマテリアルの準備と適用方法
まずは、ウィジェットにエフェクトを適用したい領域をRetainerBoxで形どります。
次にフォントマテリアルと同様に新規マテリアルを作成し、Material DomainをUserInterfaceにします。
RetainerBoxの詳細パネルのEffect Materialに、作成したマテリアルを割り当てます。Show Effects in Designerにチェックを入れるとUMGデザイナー上でエフェクトを確認できます。
波打つような変形効果を与える
以下のようにマテリアルを組みました。
(注意)RetainerBoxのEffect設定にある"Texture Parameter"と同名のテクスチャパラメータをマテリアル内に用意する必要がありますが、テクスチャは何でも大丈夫です。
[結果]
RetainerBox内の領域のみに波打つような効果が与えられました。
※UE5.3のバグだと思うのですが・・・背景部分が黒くなってしまっています。Blend ModeをAdditiveにしたら、透過できましたが、加算が入ってテキストカラーも変わってしまいました。
もちろん、テキスト以外に画像やボタンなどにどれにでもエフェクトを与えられます。
おわりに
以上、フォントマテリアルおよびエフェクトマテリアルの紹介でした。個人的に、フォントマテリアルは最初に載せた輪郭に適用したものは汎用性が高そうに感じました。
また、エフェクトマテリアルはHUDに使ってBPとの連携でパラメータを動的に変更して…などで使うとおもしろいと思います。
プロジェクトにマッチしそうなアイデアを見つけ、ぜひ使ってみてください!
参考
【Houdini】スプラッシュ画面が表示されるだけで起動しない
個人的備忘メモ
環境:Windows 11
Houdini 19.5.716(indie版使用)
概要
以前使っていたPCでも、新調したPCでも同様の問題が起きていた。
具体的には、ランチャーからの起動でも、直接houdini.exeを開いての起動でもスプラッシュ画面が表示されて数秒後に、スプラッシュ画面が消えるだけで結局起動しない。
その後、何度か試しても時々スプラッシュ画面が表示されるが同様に起動しない。
スプラッシュ画面が表示されない場合のほうが多く、青い読み込みの表示がマウスカーソルの横に出るだけである。
なお、原因を調べようとイベントビューアーを確認したところ、Windowsのntdll.dllというものに障害が発生とのことだったが、なぜなのかよくわからない。
調べたところ同様の事例がかなり多く報告されているのに対し、いまだに解決策が明確でない状況である。
今回は、調べても出てこなかった対策のひとつのメモとしつつも、同様の症状が出ている方の参考になれば幸いだと思ったので共有する。
もしこれで治った方がいれば、記事の下部にある★ボタンを押してくださると嬉しいです。
対策として試したこと
以下、効果がなかったことリスト。
・Windows再インストール⇒実際には行っていないが、新調しても発生したので意味がないと思われる
・Houdiniやライセンスサーバー再インストール
・Houdiniを管理者として実行
・ファイアウォール無効化
・DocumentフォルダにあるHoudini19.5のフォルダ削除
・ライセンスサーバーをサービスから再起動
効果があったもの(確実に有効かは不明)
・私の場合、どうもウイルスバスターが悪さをしているみたいだったので、以下の「コンピュータの保護設定」でhoudini.exeをスキャンの対象外に設定した。
※私が使用しているライセンスはIndie版だが、設定するのはhindie.exeではなくhoudini.exeで良いと思う。
これだけで、Houdiniが起動しないなんてことはなくなってしまった。ウイルスバスターでない方も、ウイルス対策ソフトを疑ってみるとよいかもしれない。
注意点
フォルダシールドの設定画面からも「許可するプログラムの一覧」という上記と似たような設定画面が出てくる。が、こちらは上記の設定とはまた別の設定であり、こちらにhoudini.exeを設定しても効果がなかった(上記の「コンピュータの保護設定」でhoudini.exeをスキャン対象外としても、以下の「許可するプログラムの一覧」には登録されない)。
【UE5】Proceduralなナンバープレートのマテリアルを組んでみる
目次
0.はじめに
今回組んでみたのは、様々な組み合わせの番号や用途表示などに対応可能なナンバープレートのマテリアルです・・・というのはあくまで具体例で、実際のところやっていることを抽象的に言えば、
「あるテクスチャの任意の範囲だけ」を「任意のモデルの任意のUV座標範囲」に合成するというものです。
イメージはこんな感じ↓
今回のナンバープレートの場合で言うと、何も書かれていない"更地"のナンバープレートに、数字や文字を合成していくイメージですね。
この方法は、色々なことに使えると思います。例えば、
【例1】UV空間のほんの一部にしか発光する部分を持たないオブジェクトで、わざわざ4K解像度のベースカラーテクスチャのAチャンネルをエミッシブのマスクに使いたくない場合
⇒今回の手法を使えば必要最低限のサイズ(64x64サイズなど)のエミッシブマスクを用意すればよくなります。
【例2】学校の教室のプレートや看板など、ベース部分を使いまわしたい場合
⇒今回紹介するナンバープレートと同じパターンです。
きっかけはGhostwire: Tokyoで車が様々なナンバーだったのを見かけたことです。最初はテキストレンダーコンポーネントでも仕込んであるかと思ったんですが、ちゃんと文字がプレート表面から盛り上がっている=ノーマル情報があるんですよね。ただ、Ghostwire: Tokyoの車で使われている数字は完全にランダムではなく何らかの規則性はありそうな気がします。
1.実装例
今回使用したUEはバージョン5.1.1です。
1-1.完成形
以下の動画をご覧ください。
付与した機能は色々ありますが、本記事で取り上げるのは以下の2つです。
①ナンバー(10-00~99-99)が、ランダム変化する
⇒1~3桁ナンバーには対応させていないのでご了承ください。そこまで難しいことではないですが、対応させるには別途改変する必要があります。
②手動でも設定可能にする
⇒今回は、①②を実現するため最終的にBP Actorにします。
1-2.用意するもの
・単純なアトラス化が施されたテクスチャ(合成したいもの)
※もちろんアトラス化されていないものでも大丈夫です(補足参照)。
今回は、R+Gチャンネルに法線情報、Bチャンネルにマスク情報を持つテクスチャを用意しました(上から順にR+G+B,R+G,B)。
※ブログ用に作ったものなのですごく雑ですし、サイズも圧縮のことも何も考えていません。ナンバーって特殊なフォントだなあ…。
単純なアトラス化と言っているのは「要素が等間隔に分割されているもの」を指しており、上のテクスチャはどちらも各数字が等間隔に配置されています。
Tips:
・必要な解像度は使用する自動車モデルに使われているテクスチャの解像度に合うようにすることを推奨します。
・3桁ナンバーなどに対応させる場合は「・」もテクスチャに含めないといけません。
1-3.マテリアルの作成
最初はBチャンネルのマスク情報を使って合成するための準備段階から始めるので留意ください!!
1-3-1.テクスチャの任意の範囲を切り取る
まず最初に、冒頭で述べた
「あるテクスチャの任意の範囲だけ」を「任意のモデルの任意のUV座標範囲」に合成する
の、「あるテクスチャ(この例では、合成に使うテクスチャ)の任意の範囲」を切り取ることから始めます。
エンジンに標準で用意されているFlipBookというマテリアル関数を使うだけでこれを実現できます。以下(紫色でコメントされた部分)をご覧ください。
0123456789から3だけが切り取られています。上の画像では、Numberというパラメータに与えられた数字が切り取られるようにしています。
Tips:FlipBookは本来的には、エフェクトに使う連番テクスチャを入力して、Animation Phaseの値を変化させることでパラパラ漫画のようにアニメーションさせることに使うことが多いと思います。
1-3-2.任意のUV座標範囲を切り取る
次は、
「あるテクスチャの任意の範囲だけ」を「任意のモデルの任意のUV座標範囲」に合成する
の、「任意のモデルの任意のUV座標範囲」を切り取ることを行います。
こちらもエンジンに標準で用意されているTextureCroppingというマテリアル関数を使うだけでこれを実現できます。以下(茶色でコメントされた部分)をご覧ください。
UpperLeftCorner(V2)およびLowerRightCorner(V2)という入力を与える必要があります。これは切り取りたいUV範囲の正規化座標となります。
1-3-3.ナンバーを合成したい場所に合わせてポジショニングとスケーリングする
ここまでできたら、先ほどの1-3-1で得られた「切り取られたナンバー」を、合成したい範囲の大きさに合わせてポジショニングおよびスケーリングしていきます。
厳密に言えば、「タイリングをした後に、必要な部分のみを残す」といったことを行います。
以下のように1-3-2で使ったTextureCroppingのCrop UVsという出力を、FlipBookのUVsに与えてやると、FlipBookの出力にタイリングをかけることができます。
次に、タイリングで作られる不要部分を除去するためには、Crop Maskという出力が、切り取られた範囲のマスク情報として使えます。
それでは、以下のようにFlipBook(タイリングされたナンバー)から、不要部分をマスクで除去します。なお、途中でBチャンネルをマスクしているのは、Bチャンネルには文字部分のマスク情報があるため、Crop Maskと乗算することで、CropMaskにある範囲内かつ数字のみのマスク情報というのを作ることができるためです。最終出力はMaskedNumberというNamed Rerouteに格納しました。この情報を後々使いまわします。
1-3-4.カラー情報を合成する
ようやくカラーや法線を合成する準備が整いましたので、まずはカラーから乗せていきますが、これは簡単です。ナンバープレートのベースカラーテクスチャに対して、先ほどのマスク情報を使ってLerpで合成するだけです。
1-3-5.法線情報を合成する
まずは、合成する法線情報を作ります。以下のようにマテリアルを組みます。
1-2で説明したように、今回用意したテクスチャはR+Gチャンネルに法線情報があるだけであってBチャンネルを再構築する必要があるため、DeriveNormalZを使って法線情報を再構築します。その後、ナンバー以外の部分はFlattenNormalによって平坦化し、強度調整用のFlattenNormalも別途配置します。
あとは、BlendAngleCorrectedNormalsを使って、ナンバープレートのベースの法線マップに対して合成をかけます。
1-3-6.4桁ナンバーにする
4桁ナンバーにするにあたって、まずはマテリアル関数化し、コンパクトにしました。
マテリアル関数内の、TextureCroppingのところも少し変更しています。
あとは、この関数を4桁分=4つ配置して合成します。
NumberSizeのパラメータのみ使いまわしています。さすがに若干コストが高くなります。とりあえずこれで一通りは完了です!あとはランダム化に対応していきましょう。
1-4.ランダム化への対応
1-4-1.Custom Primitive Data
Material Instance Dynamics(MID)を使っても可能なのですが、今回はCustom Primitive Data(CPD)を使います。
MIDではスカラーパラメータとベクターパラメータに加えて各種テクスチャパラメータなどを動的に変更可能なのに対し、CPDではスカラーパラメータとベクターパラメータしか扱えませんが、今回のケースではCPDで十分に対応できます。
また、CPDのほうがドローコールを節約するうえで特に有効な手段ですので、CPDで対応できるものは積極的にCPDを利用したほうがよいです。これについては公式ドキュメントを一読しておくことを推奨します。
マテリアル内のNumber_1~Number_4に、Custom Primitive Dataを使うように設定します。
パラメータを選択した状態で、詳細タブからUse Custom Primitive Dataにチェックを入れて、Primitive Data Indexを指定します。
今回は、Number_1~Number_4の順に、Primitive Data Indexに1~4を割り当てました。
1-4-2.Actorを継承したBPクラスを作成
今回は、Actorクラスを継承したBP_LicensePlateMatTestを作成しました。この中のBP処理にてランダム化対応を実装していきます。
あとはConstruction Scriptにて、それぞれのCustom Primitive Dataに0~9のランダムな値を与えてやるだけです。また、4桁の場合、先頭に0はこないので、先頭のみ1~9となるようにしています。
ここまででランダムナンバーは終わりです!お疲れ様でした。次はオプション的なものですが、手動設定にも対応させていきます。
1-5.手動設定への対応
すぐにできます。それぞれのナンバーに対応する変数と、手動で設定するかどうかを決めるbool変数を用意します(目玉マークが開いているようにすること)
あとは以下のように、分岐処理を組んであげるだけです。
レベル上で編集してみると、手動設定が機能していることを確認できます。
おしまい!
補足
アトラス化されていないテクスチャを使用する場合
切り取る必要がないということなので、FlipBookを使わずにTextureSampleを使用するだけです。
BP Actorにせず、単なるStaticMeshActorで実現したい
ナンバーランダム化の柔軟性が落ち、手動設定機能も失われますが、以下のようにすればできます。この例では、シェーダー内でナンバーを自動で決めることによってBPで数値を変更しなくてもよくなっています。ただし、4桁全てをバラバラにするためには更なる工夫が必要です。
シェーダーコストを下げたい
以下のような対応で、多少は下がると思います。
・標準のFlipBookでは冗長なので、必要な計算だけを残したカスタムのマテリアル関数を作成しましょう。
・標準のTextureCroppingでは冗長なので、必要な計算だけを残したカスタムのマテリアル関数を作成しましょう。
・合成する部分の数が多いほどTextureSampleが増えたりとそれなりにコストも増加していきます。ナンバープレートの場合は、ナンバー4桁=4つ以上は合成する部分が必要になりますが、それ以外はある程度妥協しましょう。FlipBook内でも、TextureCropping内でもTextureSampleが使われているので注意。
【UE5】EQSを使って遮蔽物によるインタラクションアイコンの表示・非表示を実装してみる
本記事は、Unreal Engine (UE) Advent Calendar 2022の18日目の記事になります。
目次
はじめに
本記事では、UEのEQS(Environment Query System;環境クエリシステム)を使って、アイテムピックアップ、ドア開閉などのインタラクション可能なオブジェクトのアイコンを遮蔽物の有無によって表示・非表示を切り替える機能を実装していきたいと思います。
※後述しますが、この方法、正直効果的ではないです。あくまで「EQSを使ってみた」だけのもので、利点は、実装がシンプルでわかりやすいくらいかなと思ってます(インタラクティブなオブジェクトにトレースなどの処理を書かなくて良いため)。プロトタイプや簡単なプロジェクトに使う分にはいいかもしれません。
なお、今回使用したバージョンは5.1です。
上記の公式ドキュメントによれば「EQS のユースケースの例としては、最も近い体力のピックアップや弾薬を探したり、どの敵が最も脅威となっているのかを把握したり、プレイヤーが見える位置を見つけたりすることが挙げられます」と記載されており、EQSはUE標準のAIビヘイビアツリーなどと組み合わせることで様々な環境に対応可能なAIの作成に活用できるものですが、今回はあえてオブジェクトのアイコン表示に使ってみました。
完成形
作成したものの完成形は以下のような感じ。
インタラクション可能なオブジェクトが遮蔽物の奥に隠れている場合、アイコンが非表示になります。
厳密に言えば、Querierとなるキャラクターのカメラ位置からインタラクティブなオブジェクトの原点位置との間に遮蔽物があるかどうかを見ています。この時点でなんとなく、最初に注意点として述べた理由がわかるかと思います。
ウィジェットコンポーネントについて
インタラクティブなオブジェクトにアイコンを表示しようとした場合、ウィジェットコンポーネントをアクターに取り付けることが多いかと思います。
そしてウィジェットの描画方法としては、
・スクリーン空間 ⇒ワールド座標をもとにスクリーン座標に2Dウィジェットを描画
・ワールド空間 ⇒ワールド座標に3Dウィジェットを描画
があります。
ワールド空間であれば特に何もせずとも遮蔽物の奥のアイコンは隠れるのですが、
「カメラとの距離に応じて表示サイズが変わる」「3Dウィジェットのため3次元の向きを持つ(後ろから見ると反転して見える)」などといった挙動となります。
反対に、スクリーン空間であれば上記とは逆で「カメラとの距離によって表示サイズは変わらない」「常に正面を向いている」といった挙動にはなりますが、遮蔽物の奥にあったとしても関係なしに画面に描画されます。
このように、どちらの描画方法も一長一短ですが、今回のようなインタラクションアイコンや敵のHPバーなどといったものに対しては、一般にスクリーン空間での描画が適しています。
しかし、繰り返しにはなりますがスクリーン空間への描画をそのまま使うと冒頭で示した動画のような、遮蔽によるアイコンの表示・非表示というのができません。仮にこれをBPのみで実装しようとすると、ちょっと面倒だったりします。
このため、今回は上述のEQS機能のひとつである「プレイヤーが見える位置を見つけたりすること」を使ってサクッと簡単に実装していきます。
実装
準備
使用するUEのバージョンによっては、プロジェクト内の[Editor Preferences (エディタの環境設定)] > [Experimental (実験的)] > [AI]セクションで、Environment Querying Systemをオンにする必要があります。UE5.1ではそもそも項目が見つからないはずです。
※画像は公式ドキュメントから引用
環境クエリの作成
まずはコンテンツブラウザの右クリックメニューから環境クエリを作成します。
作成されたアセットを開くと、ビヘイビアツリーのようなエディタ(クエリグラフ)が開きます。
最初から置いてある、ルートノードからドラッグ操作で出てくる[Actors Of Class]を選択します。
これは、GetActorsOfClassに近いものであって、詳細パネルから取得したいアクタークラスと、球状のサーチを行うかどうかなどを設定できます。
今回は、BP_Interactableというクラスをサーチするので、先に作成し、以下のように[Searched Actor Class]に設定しておきます。
Generate Only Actors in Radiusは、TrueであればSearch Radiusで設定された半径の球状の範囲内のSearched Actor Classオブジェクトをサーチします。Falseであればワールド全体からサーチします。
Search Radiusは後ほどキャラクタークラスからクエリにパラメータを与えるため、Query Paramsにしておきます。
Search Centerはサーチの中心位置です。デフォルトのEnvQueryContext_Querierのままでも大丈夫ですが、今回はカメラ位置を中心にしたいので、コンテンツブラウザ右クリックから[EnvQueryContext_BrueprintBase]を作成します。これによって、Querierの情報をもとにカスタムの位置情報などを作成できます。
作成したらアセットを開き、Provide Single Location関数をオーバーライドします。これで、Querierの位置をキャラクター原点ではなくてカメラ位置にオーバーライドできます。
これができたら、先ほどのSearch Centerに、作成したEnvQueryContextを設定します。
次に、クエリグラフに戻ってActors Of Classノードを右クリックして[テストを追加]>[Trace]を選びます。
Actors Of ClassノードにTraceという項目が追加されるので選択すると、詳細を設定できます。
設定は以下のようにします。
[Context]に先ほど作成したカメラ位置を使えるようにするEnvQueryContextを設定します。
これで、このクエリを実行すると、
カメラ位置を中心とするSearch Radius半径の球内に存在するBP_Interactableオブジェクトを取得⇒取得された全てのBP_Interactableオブジェクトの原点位置からカメラ位置にトレースによって遮蔽物があるオブジェクトについてはクエリ終了後の最終的な出力から弾かれる。といった具合になります。
プレイヤーキャラクターの作成
まずは、近くにあるBP_Interactableを検出するためのコリジョンコンポーネントを追加します。
※InteractableCollisonは詳細パネルから全チャンネルへの応答をオーバーラップにしていますが、インタラクティブなオブジェクトのみをオーバーラップ、他のアクターやコンポーネントに対しては応答を無視にするとなお良いです。
BeginPlayイベントで色々とセットアップするので、Enable Interactable Detectionというカスタムイベントを追加します。
以下がイベントの中身です。コリジョンの半径を設定したり、オーバーラップイベントなどを作成しています。
コリジョン内のBP_InteractableはInteractable配列内に格納されます。
次はSequenceノードの2つ目からの内容です。先ほど、クエリグラフのActors Of Classノードにてサーチ半径にパラメータを使うことに設定していたので、キャラクターのBPから与えてやります。
UpdateInteractionIconイベントでは、球体内に存在するBP_Interactableに対して、それぞれの可視・不可視に応じてウィジェットの可視性をトグルしています(次項参照)。
インタラクティブなオブジェクトの作成
Actorクラスを継承したBP_Interactableは、スタティックメッシュコンポーネントと、ウィジェットコンポーネントを追加しただけの単純なものです。
ウィジェットコンポーネントの詳細設定にて描画をScreenにしておき、ウィジェットの可視性(Visibility)はデフォルト値をFalseにしておきます。ウィジェットクラスには自作のアイコン表示用ウィジェットを設定してください(作成は割愛)。
キャラクタークラスから実行していたToggle Iconイベントは以下の通り。
⇒実装おしまい
おわりに
というわけで、今回はEQSを使って遮蔽物の有無によるインタラクションアイコンの表示・非表示をできるようにしてみました。
実際にはトレースを飛ばし続けてさらに近づいたときに、あとはボタンを押すだけでインタラクトできることを示すようにアイコンの見た目を変えたり、もちろんインタラクション処理も追加実装する必要があります。
そしてかなりデメリットであるのが、プロジェクトによっては複数の引き出しをコンポーネントとして持つタンスなどのアクターを作成する場合です。この場合、今回の方法を用いると、アクター(タンス自体)の原点の位置情報が使われるため、タンスの原点さえ見えていれば全ての引き出しに対してアイコンが表示されてしまうといったことが生じうるため根本から方法を変えるか大幅な変更を行う必要などが出てきますので、それでも良ければ構わないのですが、できれば今回の方法でも十分なプロジェクトやプロトタイプ程度に使うのが良いかと思います。
また、タイマーでクエリを実行していますが、For Each Loopによるオブジェクト毎へのウィジェット情報の更新を行いますし、クエリのActors Of Classも決して処理負荷的に優しいものではないという点にご留意ください。
なので、ちゃんと実装する場合は、素直にC++を使うのがいいです。
対象Actorの速度を監視するAbilityTask
概要
GASにてダッシュアビリティ(GA_Run)を実装した際、ダッシュのアクション入力をすると止まっているにも関わらずGA_Runの持つState.RunningのようなGameplayTagが付与されてしまうのが気になっていました。
AbilityTaskですが、どうやらTick動作させることができるみたいなので、それを利用してActorの速度を監視するAbilityTaskを作りました。
AbilityTaskの作り方については、あいす氏の記事でわかりやすく解説されていますのでそちらをご覧ください。 また、公式の詳しい作成手順はAbilityTask.h内に示されています。
[UE] AbilityTask のつくりかた - Qiita
使用UEバージョン:5.0.3
作成するAbilityTask
今回作ったものは以下のようなものです。
AbilityTaskを実行するとTargetに接続したActorの速度(高さ方向は無視)を監視し続け、Threshold(閾値)を超えるとOnStartMovingデリゲートが発行され、再度Threshold以下となるとOnStopMovingデリゲートが発行されるといった非常にシンプルな構成になっています。
実装
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FWaitGroundMovingDelegate); UCLASS() class YOURPROJECT_API UAbilityTask_WaitGroundMoving : public UAbilityTask { GENERATED_BODY() UPROPERTY(BlueprintAssignable) FWaitGroundMovingDelegate OnStartMoving; UPROPERTY(BlueprintAssignable) FWaitGroundMovingDelegate OnStopMoving; virtual void TickTask(float DeltaTime) override; /** TargetActorのXY速度が閾値Thresholdを上回る、又は、Threshold以下となるのを待つ */ UFUNCTION(BlueprintCallable, Category = "Ability|Custom|Tasks", meta = (DisplayName= "WaitGroundMoving", HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE")) static UAbilityTask_WaitGroundMoving* CreateWaitGroundMoving(UGameplayAbility* OwningAbility, AActor* Target, float Threshold); virtual void Activate() override; protected: UPROPERTY() AActor* TargetActor; float Threshold; private: bool bIsMoving; };
#include "Kismet/KismetMathLibrary.h" void UAbilityTask_WaitGroundMoving::TickTask(float DeltaTime) { if (TargetActor) { float GroundSpeed = UKismetMathLibrary::VSizeXY(TargetActor->GetVelocity()); if (GroundSpeed > Threshold) { if (!bIsMoving) { if (ShouldBroadcastAbilityTaskDelegates()) { OnStartMoving.Broadcast(); } bIsMoving = true; } } else { if (bIsMoving) { if (ShouldBroadcastAbilityTaskDelegates()) { OnStopMoving.Broadcast(); } bIsMoving = false; } } } else { ABILITY_LOG(Warning, TEXT("UAbilityTask_WaitGroundMoving ticked without a valid Actor. ending.")); EndTask(); } } UAbilityTask_WaitGroundMoving* UAbilityTask_WaitGroundMoving::CreateWaitGroundMoving( UGameplayAbility* OwningAbility, AActor* InTarget, float InThreshold) { auto* MyObj = NewAbilityTask<ThisClass>(OwningAbility); MyObj->bTickingTask = true; //Tick動作に必要 MyObj->TargetActor = InTarget; MyObj->Threshold = InThreshold; return MyObj; } void UAbilityTask_WaitGroundMoving::Activate() { SetWaitingOnRemotePlayerData(); }
MetaSoundでお手軽ラジオボイス風表現
タイトル通りです。
なんとなく「外部ソフトを使用せずにUE5内でプロシージャルにラジオ風音声に変換したいな」と思ったので紹介します。
※MetaSoundの基本的な使い方は省略します。使用するにはプラグインをONにしてください。
また、音声サンプルはありません。
使用バージョン:UE5.0.3
フィルタを使ってこもったような音声にする
まだMetaSoundをほとんど触ったことがなく、機能を把握しきれていないので今回は単純にLPF(Low-pass filter)とHPF(High-pass filter)+αを使っていきます。もちろんBPF(Band-pass filter)でもできるはずです。
LPFは、所定の周波数以上の成分をカットするフィルターで、HPFはその逆です。
手順は以下の通りです。
①入力ノードのOn PlayピンからWave PlayerノードのPlayピンに接続して音声アセットを再生できるようにします。
②Wave PlayerノードのOut Leftピンから、ワンポールハイパスフィルタノード(HPF)のInピンに接続します。
下図の例では、カットオフ周波数を"3000"に設定しているので、3000Hz以上の周波数成分を通します(数値は割と適当なので調節してください)。
なお、今回はデフォルト設定のモノラル音声のまま進めるので、Wave PlayerノードのOut Rightピンは使用しません。
③ワンポールハイパスフィルタノードのOutピンからワンポールローパスフィルタノード(LPF)のInピンに接続します。
再生してみるとわかりますが、元の音声に比べてこもったような感じになっていると思います。
音質を悪くする
先ほどまでの状態でこもった音声にはなりますが、元の音声の品質が高いとまだまだラジオっぽくなりません。
そこで、Bitcrusherノードなるものを、フィルタを通した先に接続します。
これは、ノードの説明にもあるように「入力オーディオ信号をダウンサンプルし、ビット深度も下げる」ものみたいなので使えそうだなと思いました。
サンプルレートとビット深度をお好みに合わせて調節してください。
これで再生してみると、音質が低下したことで更にラジオっぽくなっていると思います。
仕上げにノイズを追加する
先ほどまでで声のいじくりは終わったので、最後は仕上げにノイズを乗せることでよりラジオっぽくしていきますが、ノイズを追加するかどうかは必要に応じて選択してください。
手順は以下の通りです。
①ノイズノードを出して、出力をPink NoiseかWhite Noiseかを選択する。
②今回はモノラル音声なのでMono Mixer (2)ノードで声とノイズをミックスする。
③声とノイズのゲインを調節する。
いかがでしょうか。
元の音声と比べるとだいぶラジオっぽくなっていると思います。
これで、わざわざ外部ソフトで加工しなくてもUE5内で完結できちゃいますね。また、パラメータを変数化して元の音声ファイルを残したままプロシージャルに調節可能なのもMetaSoundの大きな利点だと思います。
使い方を調べながら検証するつもりが思ったよりも使いやすかったため、一瞬で記事まで書けてしまいました。
つまり、MetaSoundは素晴らしい!
以上