
目次
※この記事で使用しているUnrealのVersionは04.22.0 です。
※この記事のサンプルプロジェクトは以下URLにアップされています。
サンプルプロジェクト
・今回参考にした記事
[UE4] UE 4.22 の新機能!Sound Submix のスペクトル解析について
→こちらは、4.22から使えるようになった機能のご紹介をしています。
モーショングラフィックスのためのUnreal Engine(5) サウンドのビジュアライズ
→こちらは、この記事では機能を使いませんが、SoundVisualizationsPluginを使った機能のご紹介をしております。
↑は、かなり参考になりますので是非一読してほしいです。
Editorの下準備 レベル【★★☆】
4.22から正式に使えるようになった「AnalyzingOutput」という音声の解析機能を使って、同じく4.22から使えるようになった「EditorUtilityWidget」を駆使して、エディター内にあるSoundWaveアセットからオーディオプレイヤーみたいなものを作ってみたいと思います。
※別にEditorUtilityWidgetを使わなくてもいいのですが、個人的にEditorUtilityWidgetが好きなのと、某本社のお〇〇さんが激押ししているそうなので、布教するために合わせて使いたいと思います。
とりあえず目標としてはこんな感じのものを作ります。
初めに、エディターを起動する前の準備をしたいと思います。
※修正追記
以下プラグイン導入はは不要な工程ですので、スキップしてください。
—————————————————————————————————————————
まずはVer4.22で作ったプロジェクトを開き、プラグインを有効にします。
エディター左上にある「編集」→「プラグイン」を選択して、出てきたプラグインウィンドウ内の「Audio」カテゴリから、「Sound Visualizations Plugin」と書かれているところのチェックボックスにチェックをつけます。


出来たら一度エディターを閉じて、プロジェクトフォルダをエクスプローラー上で直接開きます。
—————————————————————————————————————————
エディターを起動する際に、「-audiomixer」というコマンドを渡してあげないと、SoundVisualizeの機能が使えないので、コマンドを渡して起動させる以下のようなbatファイルを作成します。
"[UE4Editor.exeのパス]" "[.uprojectのパス]" -audiomixer
※例

“C:\UE4\UE_4.22\Engine\Binaries\Win64\UE4Editor.exe” “C:\KA_SoundVisualize\KA_SoundVisualize.uproject” -audiomixer
これを実行してエディターを起動させると、「アウトプットログ」内のログの「Commind Line:」という部分に「 -audiomixer」という表示が出ます。

これでSoundVisualizerを使用する準備ができました!
※サンプルプロジェクトにあるバッチファイルは、使い勝手を良くするために別ファイルにファイル名を書き込む方式にしています。StartConfig.txt内の1行名に”[UE4Editor.exeのパス]”2行目に”[.uprojectのパス]”を入力してからbatを実行してください。

簡単なオーディオプレイヤーを作る レベル【★★☆】
次は、音声解析をした結果を反映するためのメモリのようなマテリアルを作りたいと思います。
まずはマテリアルアセットを新規で作ってください。

作成したらダブルクリックして、中身を編集します。
まずは、「詳細」ウィンドウ内の「Material Domain」を「UserInterface」に、「BlendMode」を「Masked」にします。

出来ましたら、処理を書いていきます。



やっている内容としては、時間で色をグラデーションさせるのと、バーを目盛り状の見た目にして、長さをScalarParameterで調整できるようにしています。
作成できましたら、いったん閉じます。
続いて、サウンドの並列処理(SoundConcurrency)アセットを作成します。
コンテンツブラウザの「新規作成」→「サウンド」→「サウンドの並列処理」を選択します。

これは、複数のサウンドが重なって再生されないように制御するために使用します。
作成したら中を開いてみましょう。
中の詳細の「MaxCount」という部分の数を「1」にしましょう。

これで、このアセットを設定したサウンドは、同時に再生できるサウンドの数が1つになります。
一旦このアセットを閉じて、次に「サウンドリスト用のウィジェット」と「ビジュアライズ用のウイジェット」の2つのベースとなるWidgetBPをそれぞれ作成します。
コンテンツブラウザの「新規作成」→「ユーザーインターフェース」→「ウィジェットブループリント」を選択します。 (2つ作ってください)

1つめのBPを開きます。
中には、「アセット名」「時間」ようのテキストと、「アセットを開く」「プレイ」用のボタンを追加します。
また、カーソルを合わせた際に、その部分をうっすらオレンジにしたいので、「image」アセットを一番後ろのZOrderに設定して置いておきます。

ウィジェットを配置できましたら、「グラフ」ウィンドウを開きます。
まず、ブループリントを書いていく前に、「Integer」変数1つと、IntegerをInputに持った「イベントディスパッチャー」を2つ用意します。


次にブループリントを書いていきます。

・カーソルがHoverしているかをTickで判定してImageWidgetのOpacityを切り替える
・ボタンが押された際にそれぞれのディスパッチャーを呼ぶ
という処理を書きました。
さらに関数も一つ追加しておきます。

出来ましたらこのBPは閉じて、もう一つの作成したWidgetBPを開きます。
中に配置するのはImageWidgetのみを配置します。
そして、そのImageの詳細の「Appearance」→「Image」に、先ほど作成したサウンドビジュアライズ用マテリアルを設定します。
また、 「Appearance」→ 「Image Size」を(X=22.0,Y=640.0)に設定します。

こちらはブループリントの処理等を書かないので、ここまで出来ましたら閉じましょう。
さてここから、新しく追加された「SoundVisualize」と「EditorUtilityWidgets」の機能を駆使していきます。
まずは「EditorUtilityWidgets」を作成します。
コンテンツブラウザ左上の「新規作成」→「Editor Utilities」→「Editor Widget」を選択します。

作成できましたらダブルクリックして中を開きましょう。
↓の画像は少々見づらいですが、デフォルトであるCanvasPanel直下に「HorizontalBox」を配置し、その下の階層にSoundVisualize用のバーと、再生している詳細を表示する「CanvasPanel」、コンテンツブラウザ内にあるSoundWaveアセットを一覧表示するための「ScrollBox」を配置します。
詳細を表示する場所には、あらかじめ「Text」Widgetを配置しておきます。

出来ましたら、ブループリントをがっつり書いていきます。







「FloatDurationToText」関数の中身

「IsValidSoundWaveAsset」関数の中身

「TickControll」マクロの中身

ザーッと書いてしまいましたが、やっている内容としては、
・ウィンドウ生成時に音声解析開始。
・ウィンドウ生成時に、 サウンドビジュアライズ用のバーウィジェットを20個生成。
・ウィンドウ生成時に、コンテンツブラウザ内のアセットからSoundWaveを見つけてウィジェットで一覧を作る。
・「Play」ボタンが押されたら、サウンドの情報をテキストに表示してサウンドを再生。
・「OpenAsset」を押したら、アセットを開く
・ウィンドウが閉じたら音声解析を中断し、再生しているサウンドを止める。
が主な内容です。
サウンドビジュアライズ関連は、以下の3つのノードで実現しています。

(詳しい説明が面倒なので、気になる人はサンプルプロジェクトをダウンロードしてください。すみません)
これらの処理を実装すると以下のようなものを作成できます。

撮影の都合でOpenAssetしているのが見えませんが、再生したサウンドに合わせて音声バーが周波数ごとに上下しているのがわかります。
こんな感じでエディター上でオーディオプレイヤーを作ることで、サウンドのチェックや、上から順番にサウンドを聞いて生きたい時なんかに、外部ツールを使うことなくチェックができちゃったりします。
サウンドビジュアライズも、音を再生していることを視覚的にわからせる意味でも効果的ですし、ゲーム内に実装してゲームとリンクさせたりすると、より音との一体感が出てクオリティにも直結します。
そんな機能を、ネイティブを書かずにブループリントだけで実装できるようになってきたので、是非皆さんも使ってみてください。
・+αメモ
本当はシークバーを追加して、任意の時間から再生したり、再生している時間を視覚的にわからせる機能も入れたかったのですが、「Audio Component」のバインドイベントの「Audio PlaybackPercent」という、現在AudioComponentが再生しているサウンドの再生率を枚フレーム返してくれるという機能が、インゲームじゃないと使えなかったので割愛しました。
(というかAudioComponentのバインドイベント系は軒並み使えなかった)
※この記事で使用しているUnrealのVersionは04.22.0 です。
※この記事のサンプルプロジェクトは以下URLにアップされています。
サンプルプロジェクト