ゲーミングエディターを作る

 

f:id:yeczrtu:20200820162448p:plain

 ウィンドウの縁が7色に光るただそれだけです。(時間を無駄にしたくない人はブラウザバック推奨です)

youtu.be

やり方

7色に光るUI用のマテリアルを作成し、エディター設定の背景色に設定するだけです。

マテリアル

基本となる1色をHueShiftで色相をずらしてグラデーションを作ります。

HueShiftのHue Shift PercentageにVectorToRadialValueで作った環状の値を渡してグラデーションを作ります。

f:id:yeczrtu:20200820164639p:plain

ここにTimeを加算して時間変化するようにして、バリエーションを増やして完成

f:id:yeczrtu:20200820163714p:plain

バリエーションの増やし方

変化する時間をずらしたり、環状にせずそのままの値を使用したりしています。

一番上のSinで複数のバリエーションをブレンドしています。(Lerpを使いましょう)

また、VectorToRadialValueの値で内積を取ったものも組み合わせてみました。

f:id:yeczrtu:20200820165527p:plain

f:id:yeczrtu:20200820170055p:plain

マテリアルができたらエディタの環境設定を開いて一般の項目にあるカラーに設定することで背景が7色に光るようになります。

f:id:yeczrtu:20200820170329p:plain

 

UE4にNvidia Anselを導入する

Anselを導入する際に個人的につまずいた点を含め手順を書いていきます。

UE4のバージョンはUE4.25.3です。

 

始めに

AnselとはNvidiaGPUで使えるフォトモードのことです。

UE4のAnselプラグインを利用すれば自分のゲームに簡単にフォトモードを追加することができます。

しかしながらネット上にある情報が古く、ドキュメント通りにいかない箇所があったので記事にしました。

導入

基本的には公式ドキュメント通りに進めていきます。

Ansel公式ドキュメント↓

https://docs.unrealengine.com/ja/Engine/Plugins/Ansel/Overview/index.html

 

まずは、Anselを導入したいプロジェクトを開いてNvidia Ansel Photography Pluginを有効化します。

f:id:yeczrtu:20200818180225p:plain

Anselプラグイン

次にC:\Program Files\NVIDIA Corporation\Ansel にある NvCameraConfiguration.exeを起動してAnsel Statusの項目がEnableになっていることを確認します。(GeForce Experienceは導入済みということで進みます)

f:id:yeczrtu:20200818181304p:plain

公式ドキュメント通りなら後はスタンドアローンモードで起動してAlt + F2 を押すとAnselが起動する筈ですが

f:id:yeczrtu:20200818180852p:plain

起動しませんでした。

どうやらGeForce Experienceのオーバーレイが有効になっていると起動できないようです。

GeForce Experienceを起動して設定(右上の歯車のボタン)から全般の項目にあるゲーム内のオーバーレイを無効にします。

f:id:yeczrtu:20200818181726p:plain

無効にする

再びUE4へ戻ってスタンドアローンで起動し、Alt + F2 を押します。

f:id:yeczrtu:20200818182327p:plain

起動した

ちなみに色がおかしくなるのはF2を押すとベースカラーを表示するようになるからです。F3を押すことで元に戻せます。

これでも起動しない場合

コマンドプロンプトを起動して

cd C:\Program Files\NVIDIA Corporation\Ansel 

NvCameraEnable.exe whitelisting-everything

を入力してホワイトリストを設定します。

f:id:yeczrtu:20200818182937p:plain

 

Anselが起動できるタイミングを設定する

タイトル画面やムービー中などAnselが起動してほしくないタイミングがあると思います。

そのような場合Set Is Photography Allowed 関数を使うことでAnselが起動できるかどうかを設定することができます。

f:id:yeczrtu:20200818183924p:plain

Set Is Photography Allowed をFalseに設定した状態でAlt + F2を押すと

f:id:yeczrtu:20200818183543p:plain

Anselの利用を制限した

きちんと制限されています。

このほかにもカメラの移動速度やプレイヤーから離れることができる最大距離などを設定できる関数がブループリントのフォトグラフィーのカテゴリ(日本語の場合)にあります。

おまけ

Anselのカメラ操作

移動はWASD 上下はZX カメラのロール回転QE ピッチ、ヨー マウスのドラッグ

 

 

 

【UE4ぷちコン】第13回UE4ぷちコン振り返り 地形編

ぷちコン応募作品SAKURA FRONT LINE

https://www.youtube.com/watch?v=GxbWAluujsM

 

地形編

ぷちコンの振り返りを書いていきます。今回は一番書きやすそうな地形作成から書いていきます。

それとこの記事は、ほぼTerreSculptor2.0の備忘録になります。

 

SAKURA FRONT LINEの地形はTerreSculptor 2.0で作ったheight mapをUE4に持ってきています。UE4側では道路を配置したあとに少しスカルプトで整えた程度です。

f:id:yeczrtu:20200331115336j:plain

TerreSculptor 2.0

http://www.demenzunmedia.com/home/terresculptor/

TerreSculptor 2.0

ぷちコンの時に作ったプロジェクトがないので新規で作成しています。

Terrainのサイズは1024x1024で作成しています。このサイズはUE4に持ってくる際、ランドスケープのサイズになります。(1024x1024で大体1㎢程度)

f:id:yeczrtu:20200331114310j:plain

1024x1024を選択

次は地形にノイズを与えます。

右上のNoisemapから与えたいノイズの種類を選択します。今回はPerlinNoiseを使用しています。

峠のような道を作りたかったのでパラメーターを調整した後、それっぽくなるまでSeedガチャを引きます。

始めにPresetsでLakesを選んでいます。一番自分のイメージと近かったためです。

サイズはかなり小さめにしています。ここはUE4に持ってきてスケール感があっているか確かめつつ調整するとよいでしょう。

他にはGainを上げ、Offsetで位置を調整してコントラストを強めました。

調整する際に地形の右側にあるスクロールバーのようなものが赤色になっていると地形が振り切れている状態なので注意。

f:id:yeczrtu:20200331092640j:plain

GainとOffsetで調整

f:id:yeczrtu:20200331091339j:plain

道のイメージ

次は少し地形を変形させます。(何となくです。特に理由はありません。)

TransformからDisplaceを選択してX magnitudeとY magnitudeを調整。

f:id:yeczrtu:20200331093735j:plain

次は道らしきものを作ります。

TransformからEqualizeを選択してPresetsでTwo Terracesを使用しました。

f:id:yeczrtu:20200331095435j:plain

f:id:yeczrtu:20200331095514j:plain

before

f:id:yeczrtu:20200331095537j:plain

after

少し道っぽくなったと思います。

次は傾斜をつけます。

が、その前にこのままでは傾斜をつけた際に振り切れてしまうので高さを調整します。

ModifyからAltitudeを選択してスクロールバーのようなものがちょうど中央に来るように調整します。

f:id:yeczrtu:20200331100533j:plain

そうしたらTransformからTiltを選択して傾斜をつける方向と角度を調整します。

f:id:yeczrtu:20200331100655j:plain

少し角度をつけすぎてしまいました。

最後は地形を浸食させます。

ErosionからHydraulicを選択。

パラメーターがたくさんありますがよくわからないのでデフォルトのままでいきます。

パラメーターをデフォルトの値に戻したいときは右下のDefaultで元に戻せます。

f:id:yeczrtu:20200331101630j:plain

浸食前

f:id:yeczrtu:20200331101655j:plain

浸食後

次はErosionからRainを選択。

こちらもデフォルトのまま使います。

f:id:yeczrtu:20200331101717j:plain

雨を降らせた

次はUE4にこれを持ってきます。

CreateからTile Creatorを選択します。

Source ImageのEditor DatamapをGetして今作った地形を読み込みます。

f:id:yeczrtu:20200331103216j:plain

今回のぷちコンでは1枚のハイトマップからランドスケープを作成しています。

そのためTilesの項目は触らずにOutputでファイルを選択して(png形式)Save Tilesでハイトマップを作成します。

これでTerreSculptor 2.0での作業は終了です。

 

ここからは分割してUE4のWorld Compositionで読み込む方法です。

Tilesの項目で分割数を決めます。(3x3では読み込めなかったと思います。)

次に命名規則を設定します。"ファイル名_X0_Y0"となるようにします。

後は先ほどと同じようにハイトマップを作成します。

f:id:yeczrtu:20200331104239j:plain

UE4

ここからはUE4での作業になります。(使用バージョン rtx dlss UE4.24.3 Nvidiaのブランチです。)

まずは分割なしで持ってくる方法です。

適当なレベルを開いて新規ランドスケープを作成します。

ファイルからインポートを選択して先ほど作成したファイルを選択します。

f:id:yeczrtu:20200331110035j:plain

インポートを選択して読み込みます。

f:id:yeczrtu:20200331110348j:plain

インポートできましたが端が途切れているので解像度を調整してもう一度読み込みなおします。

f:id:yeczrtu:20200331110651j:plain

データに適合させるを押すと何故か大きくなってしまうので今回は手動で設定しました。また、高さも少し調整しています。f:id:yeczrtu:20200331110824j:plain

今度は大丈夫そうですね。

 

次はWorld Compositionを使って読み込む方法です。

ワールドセッティングでWorld Compositionを有効にします。

f:id:yeczrtu:20200331111337j:plain

次にレベルウィンドウを開き、タイル化したランドスケープをインポートを選択します。

f:id:yeczrtu:20200331112559j:plain

ここでインポートするハイトマップはタイル化したものをまとめて選択します。

また、タイルY座標を反転のチェックを外しておいてください。

f:id:yeczrtu:20200331112908j:plain

ファイルはまとめて選択。反転のチェックは外す。

インポート出来たら、サブレベルをすべて選択してロードすることで地形を表示できます。

f:id:yeczrtu:20200331113152j:plain

また、ワールドコンポジションウィンドウでミニマップを表示できます。

f:id:yeczrtu:20200331113403j:plain

地形が読み込めたので今回はこれで終わりです。

 

【UE4】サウンドビジュアライザを作るPart4最終回

続きです。

 

yeczrtu.hatenablog.com

 

f:id:yeczrtu:20191212212044j:plain

 

今回が最終回になります。

サンプルプロジェクトを公開することにしたので細かいノードの配置などは省き、どんな処理をしているのかをざっくりと書いていくことにしました。(ノードがスパゲッティ化してしまったので順を追って解説するのは難しいです)

 

サンプルプロジェクトを公開しました。

drive.google.com

 

 

 

スプライン

始めにスプラインに沿って棒を配置するものを作ります。

コンポーネントを追加からスプラインを追加し、Get Spline Lengthでスプラインの長さを取得し現在の長さをかけて棒をスプラインに割り当てていきます。次にGet Location at Distance Along SplineノードとGet Rotation at Distance Along Splineノードで位置と回転と取得します。この時インスタンスメッシュにスケールが入っていると正しい位置が得られないのでスケールが1になるようにしています。

後はこの値をAdd InstanceのTransformに入れるだけです。(ここでは棒のタイプでスイッチしています。)

f:id:yeczrtu:20191212212446j:plain

これでスプライン上に棒を配置できるようになったと思うのでレベル上で確認してみます。


スプライン

スプラインの各ポイントを選択した状態で詳細タブから直線にしたり曲線にしたりすることができます。

 

一番上の遅れて落ちてくるやつ

こんなやつです。

(音が出ます)


上のやつ

まずは上の棒を追加します。

コンストラクションスクリプトのFor Loopが終了した後にもう一度For Loopさせて棒の数だけ増やします。この際に元の棒から直線の場合、円形の場合、グリッド状の場合それぞれにオフセットを取ります。

f:id:yeczrtu:20191212223248j:plain

これで棒を追加する処理は完成した。次はこの棒を動かす処理を追加します。まずは上の棒を追加するときにループ回数を上の棒の数分多くなるように変更しました。

f:id:yeczrtu:20191212224031j:plain

次にこの棒を更新する処理を書きます。

処理は下の棒が上の棒より高い時には早く動き、低い時には一定の速度で降下してくるというものになります。

 上の棒の位置は取得できますが下の棒はスケールしか変わらないのでスケールから大体の位置を推定します。スケールの値を大体90~100倍くらいすると上の棒の位置に近い値になりました。

後はこの値を使って分岐させます。上の棒の位置より下の棒の位置が高い時はAlphaを高めに設定したLerpを下の棒の位置が低い時は一定の速度で降下してほしいのでLerpではなくInterp Toを使用しました。

f:id:yeczrtu:20191212224940j:plain

これで完成ですがこのままでは円形で向きを変えても上のやつは向きが変わらないので追加で処理を書いていく必要がありますが非常に煩雑になってしまったので省略させてもらいます。

ステップ更新

最後にこのようなものを作って終わりにしたいと思います。


ステップ

左が補間なしで右が補間ありです。

 

 

 

 

まずは棒の配置をします。

基本的には一番上の棒を追加する処理と同じでループ回数をステップの分割数だけ増やしているだけです。

f:id:yeczrtu:20191213151046j:plain

ステップの場合と一番上のやつの場合でループ回数を変えている。

 

次は棒の更新です。

こちらも一番上の棒の時と基本的には同じでループ回数を増やしただけですが棒に周波数を割り当てる際に少し工夫が必要です。

インスタンスメッシュに割り振られているIDは下の段から順に割り振られているので現在の段は棒の数で割ることで求まります。

f:id:yeczrtu:20191213150617j:plain

 あとは現在の段をIndexから引くことで同じ周波数の棒を指定します。

f:id:yeczrtu:20191213150722j:plain

 同じ周波数の棒は現在の段に応じて影響力を決めます。

現在の段をステップの分割数で割り影響力を設定してこの値をNormalize化したスペクトラムの強さが超えたらスケールを1それ以外は0という処理で動かしています。

f:id:yeczrtu:20191213151738j:plain

後は一番上のやつの時と同じです。

 

グリッド状と組み合わせてみるとなかなか面白い動きになります。

(音が出ます)


グリッドとステップ

 

ステップ更新は棒一つ一つスケールを更新しているのですが負荷が高いのでワールドスペースのマスクドマテリアルで再現した方が良いかもしれません。

 

 今回はかなり雑になってしまって申し訳ありません。

今後はもっとわかりやすくできるように精進していきたいと思います。

 

ここまで読んでくださってありがとうございます。

サンプルプロジェクトは後日公開予定です。

 

 

 

 

 

 

【UE4】サウンドビジュアライザを作るPart3

前回の続きです。

yeczrtu.hatenablog.com

f:id:yeczrtu:20191206231812j:plain

今回作るものです。

目次

片方だけ伸びるやつ

棒を片方だけ伸ばすようにするにはピボットの位置を調整する必要があります。BlenderなどのDCCツールが使える人はそちらでピボットが下に来るように調整してください。

f:id:yeczrtu:20191206233702j:plain

ピボットの位置を変えるだけ

今回はUE4しかインストールしてないといる人もいると思うのでUE4内で作ります。(下に動画があります)

ピボットが下にあるキューブを作る手順を書いていきます。

適当なレベル上で左側のモードタブからジオメトリを選択しボックスをレベルに配置します。

 詳細タブから位置を原点に持っていき、Fキーでフォーカスして原点にカメラを持っていく

ジオメトリブラシを複製して位置Zを-100に設定

(Altキーを押しながらジオメトリブラシを移動させると複製できます。)

複製前のジオメトリブラシの詳細のBrush SettingsからXとYを100にする。

複製したジオメトリブラシを詳細のBrush SettingsのBrush TypeからSubtractiveに設定

複製したものと複製前のものを選択して詳細からスタティックメッシュを作成を押す。(選択する際に複製前→複製後の順番で選択しないとピボットの位置がずれるので注意)

作成するフォルダを選択して適当な名前を付けておきます。

 

分かりずらいと思うので動画を作りました。


ピボットが下にあるキューブを作る

 

ピボットの位置をずらせたらインスタンスメッシュを変更するだけですがこれではいちいち変更するのが面倒なので変数にして後から変更できるようにします。

 

前回と同様の手順で新しい列挙型を作ります。片方だけ伸ばすほかにもロケーションを更新するものも作る予定なので3つ作って置きます。

f:id:yeczrtu:20191207003919j:plain

名前はスケール(両側)、スケール(片側)、ロケーションにしました。

次はサウンドビジュアライザのブループリントに戻ってコンストラクションスクリプトに処理を追加していきます。

コンストラクションスクリプトに移ったら空いている場所で右クリックして先ほど作った列挙型の名前で検索してスイッチノードを追加します。

f:id:yeczrtu:20191207004735j:plain

Selectionを変数へ昇格させてインスタンス編集可能にします。

f:id:yeczrtu:20191207005244j:plain

片側が選択されたときだけインスタンスメッシュをピボットが下にあるキューブに変える処理を書きます。
左上のコンポーネントタブからInstancedStaticMeshをドラッグしてきてそこからSet Static Meshと検索してSet Static Meshノードを配置します。

f:id:yeczrtu:20191207005605j:plain

Set Static MeshノードのNew Meshに作ったピボットが下にあるキューブを設定してスイッチの片側の時だけつなぎます。

f:id:yeczrtu:20191207010211j:plain

 これで片方だけ伸ばす処理は完成です。

レベル上で確認してみます。

(音が出ます)


片側をレベル上で確認した様子

 詳細から棒の動かす方向を変えるとちゃんと変わっていることが分かります。

 

円形にしたり棒の動かす方向を変えたりすれば最初の画像のようになります。

これで片方だけ伸ばす処理は終わりです。

ロケーションを更新するやつ

ここからはスケールの代わりにロケーションを更新する処理を書いていきます。

f:id:yeczrtu:20191207111526j:plain

こんなやつ

Zスケールの値をZロケーションに変えるだけなので一瞬でできます。

イベントグラフUpdata Instance Transformへ行き、更新するトランスフォームの配列のZスケールを100倍してGet Instance TransformのZトランスフォームと線形補完します。

(100倍するのはセンチメートルからメートルへ変えるためです)

そしたらMake TransformでTransform型を作り、棒の動き方でセレクトします。

f:id:yeczrtu:20191207151708j:plain

だんだんスパゲッティ化してきた

これでロケーションを更新する処理は終わりましたのでレベル上で確認してみます。


ローテーションを更新はできたが円形にしたときに方向が変わらない

ローテーションは更新されますが円形にしたときに方向が変わってくれないという問題が発生します。

これからこれを解決していきますが別にこのままでも構わないという人はグリッド上のところまで読み飛ばしてください。

 

まずはTransform型の配列を作りコンストラクションスクリプトの最後にAdd Instanceと同じ値を追加します。

f:id:yeczrtu:20191207153702j:plain

Transform型の配列を作る。

この時配列のClearも忘れずに追加しておきます。

f:id:yeczrtu:20191207153757j:plain

配列をClear

次にローテーションから棒が動く方向を決める関数を作っていきます。

左下のマイブループリントタブから関数を新規作成し、右側の詳細タブから純粋にチェックを入れます。

後は以下のような処理を書きます。

スクリーンショットも載せておきます。

f:id:yeczrtu:20191207160235j:plain

上の三角関数二つはxとyの動く向きを求めていてそこに下の三角関数で棒のPitchの値に応じてZとブレンドしています。また、xとyはこのままではローカル座標の原点からの動く向きになってしまうのでもともとの位置を足しています。

 

この関数をスペクトラムの強さを格納するところに入れ、セレクトでロケーションを更新するときだけこの値を使うようにします。

f:id:yeczrtu:20191207155345j:plain

後はロケーションを更新する処理のところをベクトルで線形補間するように変更すれば完成です。

f:id:yeczrtu:20191207155608j:plain

ベクトルで線形補間

今度は円形にして棒の向きを変えてもうまくいくようになっていると思います。

 


ちゃんと方向が変わる

 

グリッド状のやつ

 今回の最後はグリッド状のものを作っていきます。

グリッド状に配置するのは直線形の応用で直線形に並べ一定の数を超えたら横に移動して再び直線形、というのを繰り返す処理を書きます。

 

その前に棒のタイプの列挙型に新たにグリッド状を追加しておきます。

f:id:yeczrtu:20191207161736j:plain

 コンストラクションスクリプトに移ってInt型の変数を二つ作ります。

 一つはx座標もう一つはy座標を決める変数です。

先にこの変数と棒の間隔をかけてMake Transformでセレクトノードにつないでおきます。

f:id:yeczrtu:20191207183007j:plain

次にAdd Instanceの後ろでxとyの変数の値を調整する処理を書きます。

xがグリッドの一片の長さを超えたらyをプラス1してxをリセットするようにします。棒の数だけグリッド状に並ぶのでグリッドの一片の長さは棒の数の平方根で求まります。

この値とxの値を比較し、ブランチでグリッドの一片の長さを超えたらyインクリメント

し、xを0にします。

f:id:yeczrtu:20191207183813j:plain

これで完成です。

レベル上で確認してみます。


グリッド状

エミッシブなマテリアルとはあまり相性が良くないみたいですね。あと棒の数も多くなるので解析する周波数も少し多めに取った方がきれいに見えると思います。

 

今回までのBPを貼っておきます。

 コンストラクションスクリプト

イベントグラフ

 今回はこれで終わりです。おそらく次が最後になると思います。

次回もよろしくお願いします。

 

 

 

続く

 

 

【UE4】サウンドビジュアライザーを作るpart2

前回の続きです。 

yeczrtu.hatenablog.com

f:id:yeczrtu:20191205234638j:plain

まずは直線形の調整をしてから円形を作っていきます。

 

前回作ったものはスペクトラムの強さをそのままスケールの値にしていましたが、そのままでは低周波帯に対応している棒のスケールが大きすぎるのでスケールを調整していきます。

 

前回作成したブループリントFor Each Loop からトランスフォームのZスケールに値を入れている部分に対数を追加します。しかしこれだけでは値が小さくなりすぎるので適当な数値をかけてやります。

この数値は後でいじれるように変数化してインスタンス編集可能にします。

f:id:yeczrtu:20191204210846j:plain

対数の底にネイピア数を入れていますが底は何でもいいです。

Logの前にMax 1 を入れてオーバフローを防ぐ処理を忘れずに追加してください。

 

Logの代わりにClampを使うのもありだと思います。この辺は好みの問題もあると思うのでどれがいいが自分で試して決めてみてください。

(音が出ます)


そのまま、Logあり、Clampあり

Clampを使う場合の処理です。

f:id:yeczrtu:20191204213121j:plain

Clamp

 

これで直線形の処理は終わりなので確認用のブループリントを張っておきます。(コピペもできます。)

イベントグラフ

コンストラクションスクリプト

  次にマテリアルの設定をしていきます。

コンテンツブラウザの適当な場所で右クリックからマテリアルを作成してダブルクリックで開いてください。

簡単なグラデーションをする処理を書いていきます。

始めにTime、Sine、ConstantBiasScaleを追加します。

f:id:yeczrtu:20191204231457j:plain

Timeで受け取った時間をSineで-1~1の正弦波に変えて、ConstantBiasScaleで0~1の値にしています。

 このConstantBiasScaleというノードは入力値に1を加算して割る2を返すノードです。(つい最近までこのノードを知らず、毎回+1してから0.5を掛けるという処理を書いていました。)

 

 この値でLerpしてグラデーションをするので次に3ベクターとLerpを追加します。

3ベクターはキーボードの3を押しながら左クリックで出せます。LerpはLと左クリックで出せます。

 

f:id:yeczrtu:20191204232715j:plain

 次にこの3ベクターインスタンスで編集できるようにパラメータ化しておきます。(右クリックからパラメータに変換)

 それっぽい色を選んだらMakeFloat3を使ってグラデーションする色を作っていき、Lerpにつなぎます。

f:id:yeczrtu:20191204233212j:plain

次に光る強さを設定します。 Sキーと左クリックでパラメータを出してLerpとMultiply

 してエミッシブカラーにつなぎます。

f:id:yeczrtu:20191204233936j:plain

 

 これで光ったと思いますがグラデーション速度が速いのでSineをクリックして左下の詳細タブから周期を変更しておきます。

f:id:yeczrtu:20191204234213j:plain

これでいい感じになったと思います。

ついでにもう一色追加してみました。

f:id:yeczrtu:20191204234544j:plain

マテリアルはできたので適用を押してからコンテンツブラウザに戻りこのマテリアルを右クリックしてマテリアルインスタンスを作っておきます。

マテリアルインスタンスができたらサウンドビジュアライザーのブループリントを開き

InstancedStaticMeshのマテリアルに設定します。

f:id:yeczrtu:20191204235036j:plain

これで直線形は完成です。

早速レベルで確認してみましょう。

 (音が出ます)


レベル上で確認

後はパラメータをいろいろいじって自分好みにしてください。

 

それではここから円形を作っていきます。

(音が出ます)


円形

まずは動画の左側のものを作っていきます。

 作ると言っても棒を動かすロジックは直線形と同じですのでコンストラクションスクリプトを変えるだけです。

新たにブループリントを作ってもいいのですが、私は1つにまとめたいのでそのための下準備をしていきます。(コピペしてコンストラクションスクリプトだけ書き換えるという人は読み飛ばしてください。)

 

 棒のタイプを選択できるように列挙型(Enum)を作っていきます。

コンテンツブラウザから右クリック、ブループリントから列挙型を作ります。

 ダブルクリックで開いたら右上の新規を押して名前を定義していきます。

(直線と円を追加しました。)

f:id:yeczrtu:20191205190248j:plain

 名前を付けたらサウンドビジュアライザのブループリントのコンストラクションスクリプトに戻ってSelectノードを追加します。Indexには先ほど作った列挙型を選択します。(作った列挙型の名前 で検索すると出てきます。)

f:id:yeczrtu:20191205190703j:plain


あとはIndexを変数に昇格してインスタンス編集可能にすることで詳細タブから棒のタイプを選択できるようになっていると思います。

 f:id:yeczrtu:20191205193218j:plain

 これからここを切り替えると形も変わるようにしていきます。

SelectノードをMake TransformとAdd Instanceの間につなぎます。

f:id:yeczrtu:20191205193525j:plain

これで直線形を選択したとき直線形に配置されるようになりました。

 

下準備が終わったのでここから円形に配置する処理を書いていきます。

円形

 円形に配置する処理は高校で習う円の媒介変数表示を使います。

半径rの円の媒介変数表示はx=rcosθ、y=rsinθ なのでこれをそのまま使います。

f:id:yeczrtu:20191205194748j:plain

三角関数はradiansとdegreesがありますが今回はdegreesを使います。半径になる変数は新たに作っておいてください。

次に棒がどの角度にあるのかを指定します。

Indexと棒の数で除してそれに360をかけてsinとcosにつなぎます。

この時Float型にしてからでないと正しい値にならないので注意してください。

f:id:yeczrtu:20191205200459j:plain

見づらくてすみません

これで円形に配置することはできますがこのままでは縦方向に棒が伸びるのでRotationの値をいじります。

Rotationのところで右クリックして構造体ピンを分割してPitchを変数化します。この値が伸びる方向になります。ついでに中心を向くようにしておきます。

 

最後にMake TransformのピンをSelectノードの円につなげば完成ですが、

f:id:yeczrtu:20191205223702j:plain

とりあえずこの状態でレベル上で確認してみると

 (音が出ます)


何故かおかしな方向に棒が向いている

 

方向を90度に設定したはずが何故かおかしな方向を向いてしまうのでこれを修正していきます。

イベントグラフに移ってUpdate Instance TransformにつながっているZスケールとLerpの間にMaxを追加してスケールが0になることを回避します。

f:id:yeczrtu:20191205230857j:plain

Maxには0.001を入れました。

これで再度確認してみると

(音が出ます)


スケールが0になるのを回避した様子

 

うまくいきました!

パラメータをいい感じに調整すると最初の動画の左側のと同じものを作れます。

 

円形のコンストラクションスクリプトを載せておきます。

 円形の配置ができたので今回はここまでにします。

 

次回は最初の動画右側のような片方だけに伸びるものとグリッド状のものを作っていく予定です。

次回もよろしくお願いします。

 

続き

 

yeczrtu.hatenablog.com

 

 

 

 

 

 

【UE4】オーディオビジュアライザーを作るPart1

f:id:yeczrtu:20191203230914j:plain

何回かに分けて上のようなものを作っていきたいと思います。

動画↓(※音が出ます)


UE4 SoundVisualization test

 

サンプルプロジェクトを公開しました。

drive.google.com

 

UE4のバージョンは4.24p4です。 

古いバージョンのUE4を使っている場合はいろいろ設定をする必要があるので以下の記事を参考にしてみてください。

 http://historia.co.jp/archives/11784/

 

UE4のインストールの方法やプロジェクトの作成方法はここでは説明しません。適当なプロジェクトを作ってある前提で進めていきます。

 

今回は基本形となる直線形を作っていきます。(※音が出ます)

 


直線形

それでは早速作っていきます。

始めに動かす棒を作っていきます。
コンテンツブラウザから右クリックでアクターブループリントを作ってください。

名前を適当に付けたらダブルクリックして開いてコンポーネントを追加からインスタンスドスタティックメッシュを追加します。

f:id:yeczrtu:20191204115051j:plain

インスタンスメッシュを追加

 

 次にこのインスタンスメッシュに棒となるメッシュを割り当てていきます。

今回はキューブを割り当てましたが違う形状のものを使うのも面白いかもしれません。

f:id:yeczrtu:20191204115455j:plain

インスタンスメッシュにキューブを割り当て

次はコンストラクションスクリプトを使ってこのインスタンスメッシュを直線状に並べていきます。また、この際に後に必要になる周波数の配列もセットしていきます。

それでは左上のタブからコンストラクションスクリプトに切り替えて作業を始めていきます。

f:id:yeczrtu:20191204120213j:plain

コンストラクションスクリプト

インスタンスメッシュを追加するにはAdd Instanceというノードを使います。(ワールドスペースと書いてない方)

これをFor Loopを使って直線状に並べます。

f:id:yeczrtu:20191204121635j:plain

forloopとaddinstanceをつなげただけ

ここでFor LoopのLast Indexは並べる棒の数なので後から編集できるように変数化しておきます。

Last Indexのところにカーソルを持ってきて右クリックで変数に昇格を選択して名前を適当に決めて、インスタンス編集できるように目玉のアイコンをクリックしておいて


ください。それとこのままでは棒の数が一個多くなってしまうのでFirst Indexを1に設定しておきます。(棒の数-1でもOK)

f:id:yeczrtu:20191204122656j:plain

これまでの処理

 次に棒の位置を決めていきます。

 Indexに棒と棒の間隔となる数値をかけてy座標にセットする処理を書いていきます。

 まずは左下のマイブループリントのタブから変数の+を押し、棒の間隔となる変数(float型)をつくります。こちらもインスタンス編集可能にしてください。

次にこの変数とFor LoopのIndexを掛けてMakeTransformで結合してAdd Instanceにセットします。

f:id:yeczrtu:20191204124408j:plain

 ここまで出来たらコンパイルを押して、棒の数と間隔の変数のデフォルト値を調整してビューポートで確認してみてください。(変数のデフォルト値は一度コンパイルをしないと設定できません。)

 

f:id:yeczrtu:20191204124733j:plain

でかい

インスタンスメッシュが大きいのでスケールを調整しましょう。(0.02に設定しました。) 

 

 選択

f:id:yeczrtu:20191204125200j:plain

50分の一なので2アンリアルセンチメートルくらい

動かす棒ができたので次はこの棒を動かすための値を設定していきます。

始めにこれらの棒に対応する周波数を設定していきます。

 

あたらしくfloat型の配列を作ります。配列にするには変数の型の右側のアイコンから

配列に設定します。もしくは変数のアイコンを右クリックすることでも変更できます。(最近知った)

この配列にIndexと対応する周波数を掛けたものを入れていきます。

対応する周波数は解析する周波数(新しく作る)と棒の数の商で求まります。

f:id:yeczrtu:20191204130749j:plain

解析する周波数は1000~2000くらいがおすすめです。22kHzまで解析しても高周波帯のスペクトラムは弱いので棒がほとんど動かないです。

 

最後にFor Loopの前に配列を初期化する処理を追加して終了です。

f:id:yeczrtu:20191204131446j:plain

配列の要素が増えすぎないための処理

ここまで来たら一度コンパイルをして各変数のデフォルト値を適当に設定しておきましょう。

 

いよいよここから棒を動かす処理を書いていきます。

動かし方は、UE4内の音を高速フーリエ変換して先ほど作った棒に対応する周波数のスペクトラムを取得して、その値をZ軸のスケールに変換して更新するという処理になります。

まずはスペクトラムを取得する処理を書いていきます。

イベントグラフに移動してイベントBeginPlayからStartAnalyzing Outputというノードを追加します。

 

f:id:yeczrtu:20191204132932j:plain

 このノードは音を解析するノードで、▽を押して詳細を開くと色々と設定が出てきます。一番上のSubmix to Analyzeでは何も設定していない場合UE4内でなっている音すべてを解析してくれます。(はず)

FFTSizeはフーリエ変換の精度を設定できます。精度を上げるときれいに動きますがその分負荷は上がると思います。今回はMaxに設定しました。

Interpolation Mehodは補間の仕方を設定できますが違いがよくわからないので線形補間のままにしておきます。

Window Typeは窓関数です。詳しいことは説明しません。(できません)

デフォルトのままHannを使用していきます。

 

これで音を解析する処理はできたので次に解析した音のスペクトラムの強さを取得し、配列に格納していく処理を書いていきます。

Set Timer by Event をこの後につなぎ、新たにカスタムイベントを追加してそこからGet Magnitude for Frequencies でスペクトラムの強さを取得します。

f:id:yeczrtu:20191204134816j:plain

次にTransform型の配列を作り、Magnitudesの値をFor Each Loopを使って配列に追加していきます。

f:id:yeczrtu:20191204135404j:plain

Array IndexからGet instance Transformを追加して各棒のトランスフォームを取得します。次にArrayElement をZスケールとしてmake Transformで結合してTransformの配列

に入れます。

f:id:yeczrtu:20191204140050j:plain

あとはこの配列の値を使ってスケールを更新していくだけです。

 

スケールの更新はみんな大好きEvent Tickを使っていきます。

Event TickからFor LoopとUpdate Instance Transformを追加します。

f:id:yeczrtu:20191204140527j:plain

Tickに追加する処理

For LoopのLast Indexには棒の数をFirst Indexには1を設定してください。

 

次に先ほど作ったTransformの配列から値を取得して現在のトランスフォームの値と線形補間をした値をアップデートに入れます。

f:id:yeczrtu:20191204141309j:plain

ここでLerpのAlpha値を変数化しておきます。この値をいじることで棒の動きをヌルヌルした動きにしたり、カクカクした動きにしたりできます。

 

f:id:yeczrtu:20191204141930j:plain

 Alpha値なので0~1までの値になるように範囲を設定します。

 -1で反転しているのは変数名を柔らかさにしたためです。硬さなどにすればそのままでもいいと思います。

デフォルト値は0.2くらいにしました。

 

重要なことを忘れていました。For LoopのIndexをUpdate Instance Transformにつないでおいてください。

f:id:yeczrtu:20191204142934j:plain

これをつながないと動かない

これで一応動くようになったと思いますが、このままではTransformの配列に要素が追加される前に更新処理が行われてうまく動かない場合があるのでそこを修正していきます。

Transformの配列に値が格納し終わった後、Tickが動くようにします。

TickとFor Loopの間にGateを追加して、For Each LoopのCompletedからOpenにつないでください。

f:id:yeczrtu:20191204144224j:plain

カスタムイベントを使った方が見やすくなると思います。

 

ここまで来たら一度レベルに音源とこのブループリントを配置して確かめてみましょう。

 (※音が出ます)


レベルに配置した様子。

あれ?最初の動画と全然違うじゃないか!と感じた方々申し訳ありません。もう少し続きそうなので記事を分けさせてもらいました。次回は直線形の動画と同じになるようにしていきます。

インスタンス編集可能にした変数は右下の詳細からパラメータを変更することができます。

(※音が出ます)


パラメータを変更

 

とりあえずそれっぽいのもができたので今回はここまでにします。

次回は細かい修正とマテリアル、そして円形のものを作っていく予定です。

よろしくお願いします。

 

 

続き

 

yeczrtu.hatenablog.com