【UE4 .26】Niagaraで音の波形をパーティクルで表示する

 これを作ります。

 

音の波形を取得
[UE4]新機能「Audio Synesthesia」でサウンドの非リアルタイム解析!|株式会社ヒストリア

Niagaraについて

コンテンツサンプルを楽しむ”超”初心者の為のNiagara - YouTube

この二つを参考にしました。
特に、Niagaraの解説動画の方は 先に見てもらえると後の解説がわかりやすくなると思います(とっても易しくわかりやすいように解説されています)

 

作成の流れとしては

  1. AudioSynesthesiaの定Q解析で音源を解析して48個のバンド毎に数値を取り出す
  2. Niagaraで48個(バンド数分)スプライトを円形に配置して、それぞれを外側に(放射状に)回転させておく
  3. 音源のアクターを作ってパーティクルを再生。解析で取り出したバンド毎の数値をパーティクルにNiagara Set Float Arrayで配列ごと渡す
  4. パーティクル側で渡された配列を分解して、48個それぞれのスプライトに大きさ(長さ)として渡す

です。

 

まずはAudioSynesthesiaからです。

プラグインをのメニューから、有効化させます。

エディタを再起動して「追加/インポート」を開くと、サウンドの欄に「解析」とかが増えているので、その中から「Synesthesia NRT」を選択します。

f:id:ten0313:20210601134648p:plain

ConstantQNRTを選択

f:id:ten0313:20210601135036p:plain


作成された解析用のアセットを開いて、流したい音楽ファイルをSoundの欄に設定します。

f:id:ten0313:20210601135421p:plain

 

次に音を再生するアクターを作成します

f:id:ten0313:20210601140336p:plain

コンポーネントの配置はこんな感じ。Audioにはなにも設定していません。

 

変数です。

f:id:ten0313:20210601140648p:plain
Durationは曲の長さを入れておきます。後で設定します。
ConstantQNRTとSoundWaveについては以下の通りです。

f:id:ten0313:20210601140813p:plain

ConstantQNRT

f:id:ten0313:20210601140920p:plain

SoundWave

ここで詰まったことがありました。変数ConstantQNRTなのですが(型はConstantQNRTにしてください)デフォルト値を選択しようとしても、さっき作成した解析用のアセットが出てこない時があります(海外の解説動画とか見てたら"Bug! Bug!"って騒いでいたのでありがちな事らしい...?) エディタの再起動とかアセットの作りなおしとかしてたらいつのまにか候補の一覧に出てきました。

SoundWaveは 型はSoundWaveを デフォルト値は流す音源を選択してください。

 

アクターのイベントの方を設定していきます。

f:id:ten0313:20210601144002p:plain

全容はこんな感じ。

各場所を拡大します。

f:id:ten0313:20210601144025p:plain

BeginPlayでNiagaraParticleSystemを追加、アクタのシーンルートにアタッチします。その後、変数にパーティクルをセットしておきます(後程、解析した値を渡すためです)(セットするパーティクルは後程作成するので今は空っぽで大丈夫です)

f:id:ten0313:20210601144205p:plain

次の場所です。最初に 変数DurationにSoundWave、音源の長さを取得してセットします。

その後スクショの通りにノードを組みます。

f:id:ten0313:20210601144357p:plain

StartPlayではこういう事をしています。Audioコンポーネントに音源を設定して、再生しています。

 

この後に、パーティクルに解析した内容を渡す処理が続くのですが そのためにはパーティクルの方が必要なので 一旦アクターは置いておいて Niagaraを開いていきます。

 

f:id:ten0313:20210601150003p:plain

これが出来たNiagaraSystemです。
Emitterの方では特に特別な事はしていませんが、スプライトを円形に並べる・それぞれの大きさを変える処理をNiagaraModuleScriptで自作したので それも含めて設定内容を解説していきます。
自作したModuleScriptは「パーティクル更新」の中にある「NS Set Position Circle」です。それ以外の場所は、パーティクルのライフタイムを永続的に変更する・色を変更する・スプライトの向きを上に設定する(カメラの向きにしない)を設定しているだけです。慣れた人はここから少し読み飛ばしていいと思います。

 

まず、パーティクルのライフタイムを永続させます。普通にライフタイムを設定すると、その秒数の間しか表示されないので それをなんとかします。
参考にしたのは

UE4 NiagaraのLifetimeを無制限にする方法 - PaperSloth’s diary

この記事です。

1.
「Particle State」Moduleの「Kill Particles When Lifetime Has Elapsed」フラグをOffにして
同Moduleの「Loop Particles Lifetime」にチェックを入れるだけです。

2.
「Particle State」Moduleの「Kill Particles When Lifetime Has Elapsed」フラグをOffにして
Lifetimeに「Normalized LoopAge」を割り当てる

3. 「Initialize Particle」と「Particle State」を使用しない

でした。

 

色を変更します。
「パーティクルのスポーン」に「Color」を追加して好きな色を設定します。

 

スプライトの向きを上に固定します

f:id:ten0313:20210601150736p:plain
SpriteRendererでFacingModeをCustomFacingVectorにします。

f:id:ten0313:20210601151014p:plain

次に「パーティクルのスポーン」にOrientMeshToVectorを追加して写真の通りに設定します。

スプライトをスポーンさせます。

f:id:ten0313:20210601151137p:plain

今回は最初からスプライト達に存在してもらってほしいので、SpawnBurstInstantaneousを利用して、48個のスプライトを同時にスポーンさせます。ここの48個とは、音源の解析で得られるバンドの数です。

次に、スプライトを円形に配置して、かつそれぞれの大きさを動的に変えられるModuleScriptを作っていきます。

f:id:ten0313:20210601151735p:plain

コンテンツブラウザで選択して新規作成します。

f:id:ten0313:20210601151841p:plain

全容としてはこんな感じです。それぞれ見ていきます。

f:id:ten0313:20210601152202p:plain

最初のマップ所得です。ここはスクリプトの引数というか、エミッタで設定した数値とかを要求したりできる箇所って考えたらいいんでしょうか。

ParticleNumは生成しているスプライトの数です。今回はSpawnBurstInstantaneousで設定した48個を使うので、デフォルト値に48を設定します。

SoundVolumeは、後で解析した値を設定するためのfloat型の配列です。

 

f:id:ten0313:20210601152844p:plain

スプライトを円形に配置するようにした所です。
下から伸びているのはマップ取得から伸ばしたParticleNumです。Sinで横軸を、Cosで縦軸を出して円形に配置します。「ExecutionIndex」は処理しているスプライトが何個目のなのかを返してくれるノードです。便利だと思います。

 

www.youtube.comModuleScriptに関して解説されているこの動画がオススメです。英語で、ちょっと訛りがあって聞き取りにくいんですけど、翻訳字幕つければ理解できると思います。
5:30くらいにExecutionIndexの説明がされています。動画で実際にうごかされている内容を見る方がわかりやすいと思います。

 

f:id:ten0313:20210601154451p:plain
今のままでは、スプライトの向きが一定なので全てがそれぞれ円の外を向くように設定しました。

 

f:id:ten0313:20210601154525p:plain

スプライトそれぞれの縦の幅を変更する所です。マップを取得から取ってきたfloatの配列から、ExecutionIndexで数値を取り出してvector2Dに変換します。Yはスプライトの幅の値です。SpriteSizeに設定します。
これでNiagaraModuleScriptは完成です。名前はNMS_SetPositionCircleにしました。

 

f:id:ten0313:20210601155602p:plain

作ったModuleScriptをエミッタのパーティクル更新に追加して 数値を写真の通りにします。SoundVolumeには「新しいUserパラメータから読み取る」を設定してください。

f:id:ten0313:20210601155708p:plain

パラメータのウィンドウから作った値を選んで、名前をSoundVolumeにします。

パーティクルの方はこれで設定完了です。

 

音楽を再生するアクタの方に戻ります。

 

f:id:ten0313:20210601160108p:plain

SpawnSystemAttachedのSystemTemplateに忘れずにさっき作ったパーテイクルを設定します。

パーティクルに解析の内容を渡していく処理を作っていきます。

 

f:id:ten0313:20210601160345p:plain

最初の方に作ったブループリントのノードの先にこういう風に繋げます。
やっている内容としては、カスタムイベントのPlaybackPercentから返される値に 音源の長さを乗算して計算の結果を同期させます。その内容をNiagaraSetFloatAttayでパーティクルのユーザー変数であるSoundVolumeにセットしています。

 

これでアクタをレベルに配置するだけで完成です。

f:id:ten0313:20210601160747p:plain

 動画のように動いているでしょうか

なにかわかりにくい事があったり、間違いがあればTwitterのDMとかにおねがいします。


[ この記事はブログ投稿者の憶測や考えによりつくられています。

よって書いてある内容に誤りや言い間違いがあるかもしれません。もし修正したほうがいい場所や「こういった言い方のほうが”ソレっぽい”よ」などがありましたら後に記載してあります、リンク先のツイッターアカウントに教えてくださると嬉しいです:) ]

 

twitter.com