【UE4】オーディオビジュアライザーを作るPart1
何回かに分けて上のようなものを作っていきたいと思います。
動画↓(※音が出ます)
サンプルプロジェクトを公開しました。
UE4のバージョンは4.24p4です。
古いバージョンのUE4を使っている場合はいろいろ設定をする必要があるので以下の記事を参考にしてみてください。
http://historia.co.jp/archives/11784/
UE4のインストールの方法やプロジェクトの作成方法はここでは説明しません。適当なプロジェクトを作ってある前提で進めていきます。
今回は基本形となる直線形を作っていきます。(※音が出ます)
それでは早速作っていきます。
始めに動かす棒を作っていきます。
コンテンツブラウザから右クリックでアクターブループリントを作ってください。
名前を適当に付けたらダブルクリックして開いてコンポーネントを追加からインスタンスドスタティックメッシュを追加します。
次にこのインスタンスメッシュに棒となるメッシュを割り当てていきます。
今回はキューブを割り当てましたが違う形状のものを使うのも面白いかもしれません。
次はコンストラクションスクリプトを使ってこのインスタンスメッシュを直線状に並べていきます。また、この際に後に必要になる周波数の配列もセットしていきます。
それでは左上のタブからコンストラクションスクリプトに切り替えて作業を始めていきます。
インスタンスメッシュを追加するにはAdd Instanceというノードを使います。(ワールドスペースと書いてない方)
これをFor Loopを使って直線状に並べます。
ここでFor LoopのLast Indexは並べる棒の数なので後から編集できるように変数化しておきます。
Last Indexのところにカーソルを持ってきて右クリックで変数に昇格を選択して名前を適当に決めて、インスタンス編集できるように目玉のアイコンをクリックしておいて
ください。それとこのままでは棒の数が一個多くなってしまうのでFirst Indexを1に設定しておきます。(棒の数-1でもOK)
次に棒の位置を決めていきます。
Indexに棒と棒の間隔となる数値をかけてy座標にセットする処理を書いていきます。
まずは左下のマイブループリントのタブから変数の+を押し、棒の間隔となる変数(float型)をつくります。こちらもインスタンス編集可能にしてください。
次にこの変数とFor LoopのIndexを掛けてMakeTransformで結合してAdd Instanceにセットします。
ここまで出来たらコンパイルを押して、棒の数と間隔の変数のデフォルト値を調整してビューポートで確認してみてください。(変数のデフォルト値は一度コンパイルをしないと設定できません。)
インスタンスメッシュが大きいのでスケールを調整しましょう。(0.02に設定しました。)
選択
動かす棒ができたので次はこの棒を動かすための値を設定していきます。
始めにこれらの棒に対応する周波数を設定していきます。
あたらしくfloat型の配列を作ります。配列にするには変数の型の右側のアイコンから
配列に設定します。もしくは変数のアイコンを右クリックすることでも変更できます。(最近知った)
この配列にIndexと対応する周波数を掛けたものを入れていきます。
対応する周波数は解析する周波数(新しく作る)と棒の数の商で求まります。
解析する周波数は1000~2000くらいがおすすめです。22kHzまで解析しても高周波帯のスペクトラムは弱いので棒がほとんど動かないです。
最後にFor Loopの前に配列を初期化する処理を追加して終了です。
ここまで来たら一度コンパイルをして各変数のデフォルト値を適当に設定しておきましょう。
いよいよここから棒を動かす処理を書いていきます。
動かし方は、UE4内の音を高速フーリエ変換して先ほど作った棒に対応する周波数のスペクトラムを取得して、その値をZ軸のスケールに変換して更新するという処理になります。
まずはスペクトラムを取得する処理を書いていきます。
イベントグラフに移動してイベントBeginPlayからStartAnalyzing Outputというノードを追加します。
このノードは音を解析するノードで、▽を押して詳細を開くと色々と設定が出てきます。一番上のSubmix to Analyzeでは何も設定していない場合UE4内でなっている音すべてを解析してくれます。(はず)
FFTSizeはフーリエ変換の精度を設定できます。精度を上げるときれいに動きますがその分負荷は上がると思います。今回はMaxに設定しました。
Interpolation Mehodは補間の仕方を設定できますが違いがよくわからないので線形補間のままにしておきます。
Window Typeは窓関数です。詳しいことは説明しません。(できません)
デフォルトのままHannを使用していきます。
これで音を解析する処理はできたので次に解析した音のスペクトラムの強さを取得し、配列に格納していく処理を書いていきます。
Set Timer by Event をこの後につなぎ、新たにカスタムイベントを追加してそこからGet Magnitude for Frequencies でスペクトラムの強さを取得します。
次にTransform型の配列を作り、Magnitudesの値をFor Each Loopを使って配列に追加していきます。
Array IndexからGet instance Transformを追加して各棒のトランスフォームを取得します。次にArrayElement をZスケールとしてmake Transformで結合してTransformの配列
に入れます。
あとはこの配列の値を使ってスケールを更新していくだけです。
スケールの更新はみんな大好きEvent Tickを使っていきます。
Event TickからFor LoopとUpdate Instance Transformを追加します。
For LoopのLast Indexには棒の数をFirst Indexには1を設定してください。
次に先ほど作ったTransformの配列から値を取得して現在のトランスフォームの値と線形補間をした値をアップデートに入れます。
ここでLerpのAlpha値を変数化しておきます。この値をいじることで棒の動きをヌルヌルした動きにしたり、カクカクした動きにしたりできます。
Alpha値なので0~1までの値になるように範囲を設定します。
-1で反転しているのは変数名を柔らかさにしたためです。硬さなどにすればそのままでもいいと思います。
デフォルト値は0.2くらいにしました。
重要なことを忘れていました。For LoopのIndexをUpdate Instance Transformにつないでおいてください。
これで一応動くようになったと思いますが、このままではTransformの配列に要素が追加される前に更新処理が行われてうまく動かない場合があるのでそこを修正していきます。
Transformの配列に値が格納し終わった後、Tickが動くようにします。
TickとFor Loopの間にGateを追加して、For Each LoopのCompletedからOpenにつないでください。
カスタムイベントを使った方が見やすくなると思います。
ここまで来たら一度レベルに音源とこのブループリントを配置して確かめてみましょう。
(※音が出ます)
あれ?最初の動画と全然違うじゃないか!と感じた方々申し訳ありません。もう少し続きそうなので記事を分けさせてもらいました。次回は直線形の動画と同じになるようにしていきます。
インスタンス編集可能にした変数は右下の詳細からパラメータを変更することができます。
(※音が出ます)
とりあえずそれっぽいのもができたので今回はここまでにします。
次回は細かい修正とマテリアル、そして円形のものを作っていく予定です。
よろしくお願いします。
続き