Unreal Engine入門(5) サウンドのビジュアライズ

UnrealEngine

概要

今回のチュートリアルのテーマはサウンドのビジュアライズです。再生中のサウンド音量を解析して、アクタの大きさと色に反映させます。プラグインの導入など、サウンド機能に特化する内容で、若干難易度が高くなってしまったので、必要でない方はこの章は読み飛ばしてください。

1.プラグインのインストール
2.マテリアルの作成
3.音量バーのクラスを作成
4.音量バークラスの寿命を設定
5.音量バーを自動的にスポーンするクラスを作成
6.一定間隔で関数を呼び出す
7.サウンドファイルの追加と再生
8.サウンドの再生イベントから再生時間を計算
9.音量の計算
10.音量をスポーンと関連づける
11.音量とマテリアルの色を関連づける

※9の音量の計算ですが、使用しているノードにバグがあり今後非推奨になるようです。詳しくはこちらのブログに記載されています。

プラグインのインストール

サウンドの解析のためにプラグイン「Sound Visualizations Plugin」を追加します。追加したプラグインを有効にするためには再起動が必要です。

マテリアルの作成

まずマテリアルを作成します。今回は照明の影響を受けないフラットな質感を用いることにします。ポイントはマテリアル内で使用している定数ノードをパラメータ化し、外部のブループリントから制御できるようにしておく事です。

・音量バー用のマテリアルを作成
・発光だけのシンプルなマテリアルにする → Shading ModelをUnlitへ
・エミッシブカラーにConstant3Vectorを入力して赤色に
・ブループリントで色を変更できるようにパラメータ化
・パラメータの名前は後に使用するので把握しておく

パラーメータ化した際の名前「Paramater Name」は後ほどブループリントで使用するので把握しおく必要があります。

音量バーのクラスを作成

音量の高さを視覚化するための棒グラフのバーのようなクラスを作成します。今回はBP_Barという名前のクラスにしました。クラス内のビューポートには立方体を加え、変数Heigitによって立方体の高さ方向のスケールが変えられるようにしておきます。

・キューブを追加
・キューブにマテリアルを適用
・高さを変更できる変数Heightを作成
・クラス生成時に変数Heightがキューブの高さを設定するようにする
・右から左へ移動するアニメーションを追加

Add Local Offsetとはアクターの位置を、指定した座標分移動させるノードです。Event Tickと組み合わせると簡単にアクタを移動させることができます。

音量バークラスの寿命を設定

クラスには寿命を秒単位で設定しておくことできます。寿命を持ったクラスをアクタとしてレベルに配置すると、寿命が尽きた瞬間に消滅(Destory)されます。

・寿命を設定して自動的に消滅するようにする → Initial Life Span
・試しにレベルに配置してプレイしてみる

・成功していたら配置したアクタは必要ないので削除

BP_Barをレベルに配置してプレイすると、1.5秒後に消滅することが分かる。この寿命パラメータですが、ゲーム制作では発射された弾などのクラスで活用されているようです。

音量バーを自動的にスポーンするクラスを作成

先ほどは手動でBP_Barをレベルに配置して試してみましたが、今度は自動的に生成されるようにしてみましょう。自動生成にはレベルブループリントを使用する方法もありますが、今回は自動生成用のクラスBP_Masterを新たに作り、このBP_Masterでサウンドの解析やBP_Barの生成を処理します。

・音量クラスを生成するためのマスター的なクラスを作成
・マスタークラス内にスポーンする「関数」を作成する

ここで関数を作成しているのは、一定間隔で処理をさせるためです。次のステップで扱うノード「Set Timer by Function Name」からこの関数が呼び出されるようになります。

プログラミング経験者にとって関数は馴染み深いものだと思います。そうでない方は、命令をグループ化し、一つのノードとして扱えるようにできるものと考えておいて良いかと思います。関数には入力ピンと出力ピンも追加可能です。

一定間隔で関数を呼び出す

一つ前のステップで作成した関数「SpawnBar」を呼び出して、自動的にBP_Barを生成してみましょう。「SpawnBar」を呼び出すタイミングとしては、EventTickも考えられますが、大量に発生しすぎてしまうので、一定間隔で関数を呼ぶ「Set Timer by Function Name」を使用します。

・タイマーをセットして一定間隔で関数を呼び出す
・自動的かつ一定間隔で音量バーがスポーンする

サウンドファイルの追加と再生

サウンドファイルをインポートするとSound Wave形式のデータとなります。このSound Waveをクラス内に追加したAudioコンポーネントにセットすればサウンドを再生できるようになります。

・サウンドファイルをインポートする
・サウンドファイルのストリーミング設定をONにする

・マスタークラス内にAudioコンポーネントを追加
・マスタークラス内にSound Wave用の変数を追加
・AudioコンポーネントにSound Waveをセットして再生する

インポートしたSoundWaveデータの「Streaming」をONにしているのは、ファイルを再度開いた際に音量がうまく取得できないことがあったためです。

サウンドの再生イベントから再生時間を計算

Audioコンポーネントにはイベントが用意されており、サウンドの再生開始や終了のタイミングを取得できます。今回使用する「On Audio Playback Percent」はサウンドが再生中に発生し続けるイベントです。このイベントを利用してサウンドの再生時間を計算できます。

・再生時間を保持する変数を作成
・Audioコンポーネントのイベントから再生時間を計算 → On Audio Playback Percent
・サウンドファイルの全体時間と再生箇所(%)から、再生時間を求める
・再生時間を変数に入力して保持しておく

Audioコンポーネントの詳細パネルの最下部に、イベントの「+」ボタンが表示されており、このボタンをクリックするとイベントグラフにイベントノードが作成されます。

音量の計算

BP_Masterにもう一つ関数を追加します。サウンドの音量を計算する関数です。サウンドの音量を取得するためにはSoundWaveから「Get Amplitude」を使用するのが一般的だと思います。しかし、私の理解不足か仕様からなのか、指定時間と取得する音量にズレが出てしまいました。

こうした理由から今回は「Calculate Frequency Spectrum」を使用し、周波数スペクトルを取得。その周波数スペクトルを10分割して合算したものを音量として使用することにしました。この10分割したデータはFloatの配列データとなっていますので、ForEachLoopを使用して合計を求めています。ちなみに配列内の数値を正の数の時だけ合計するようにすると、音量が適切に表現できるようです。

・マスタークラス内に音量を取得する関数を作成する
・関数には返り値を持たせる

・音量はCalculate Frequency Spectrumから計算して求める
・周波数スペクトルを取得して等分割する
・等分割した周波数スペクトルの正の値だけを全て合計する

・合計した値を関数からアウトプットされる返り値とする

Get Amplitudeでシンプルに音量計算できるはずなのですが、試行錯誤してもサウンド再生とタイミングが合わず断念しました。

[追記] 使用しているノードにバグがあり今後非推奨になるようです。詳しくはこちらのブログに記載されています。

音量をスポーンと関連づける

CalcSound関数内で音量の取得ができるようになりましたので、SpawnBar関数内で使用して、BP_Barの発生時にパラメーターとして音量を使用してみましょう。

・マスタークラスのスポーン関数内で音量の計算関数を呼び出す
・音量の計算関数からの返り値を、スポーンのHeightとして利用する
・音量がバーの高さに影響するようになる

CalcSound関数内で計算した音量を、SpawnのパラメータとしてBP_Bar内の立方体の高さに影響させる。

音量とマテリアルの色を関連づける

最後に音量の数値をマテリアルの色に反映させてみましょう。ポイントはマテリアルのダイナミックインスタンス化です。インスタンス化することで元のマテリアルから新たにマテリアルを生成し、動的にパラメータで質感を変化させることが可能となります。

・音量バークラス内で、マテリアルをダイナミックインスタンス化する
・Height変数で色を変更する

以前作成したマテリアル内のパラメータ名「BarColor」に数値を入力することで、マテリアルを変化させる。

まとめ

サウンドデータを解析できると様々な応用が可能となり、表現の幅も広がることでしょう。今回はシンプルな立方体の高さに音量を影響させましたが、より複雑なメッシュやパーティクルなどに影響させることで、高度な表現にもつながるはずです。

今回のチュートリアルはこれで終了です。間違いの指摘、アドバイス、ご要望などはTwitter(@zuga)までお願いします!

Related Posts

No results found

メニュー