こんにちは、電通総研金融ソリューション事業部の飯田です。
今回は、Unreal Engine 5で、音に応じてオブジェクトの位置、回転、スケールやマテリアルの表現を変化させる方法をご紹介します。
前編で位置、回転、スケールを変化させる方法、後編でマテリアルを変化させる方法をご紹介します。
検証環境 / ソフト
OS:Windows11
GPU:NVIDIA GeForce RTX 4090
Game Engine:Unreal Engine 5.2.1
実行手順
- 音データを用意する
- ブループリントを作成する
- ブループリントに、コンポーネントを追加する
- ブループリントで、音楽を再生する
- ブループリントで、Transformを動的に変化する
Unreal Engineでは、ブループリントを使用して、ゲーム内の挙動を実装していきます。
ブループリントとは、スクリプトを視覚的に実装するシステムです。
プログラミングで言う「関数」「オブジェクトの参照」「ゲームプレイイベント(ボタン押下処理の判定など)」をノードと呼ばれる四角いボックスで表現し、このノードをつなぎあわせていくことでゲーム内実装を作っていきます。
今回は、ブループリントを使って、「指定の音楽を再生」「再生している音に反応するようにオブジェクトの位置、回転、スケールが変わる」の2段階で実装していきます。
こちらの記事でも、ブループリントと衝突を使った実装を扱っています。ぜひご一読ください!
1. 音データを用意する
コンテンツブラウザ上に、再生したい音楽をドラッグ&ドロップします。
なお、音楽は.wavファイルの形式である必要があります。
これで、音楽がサウンドウェーブとして読み込まれました。
サウンドウェーブをダブルクリックすると、専用のウィンドウが開きます。
解析>Envelope>Enable Amplitude Envelope Analysisにチェックを入れて、左上のフロッピーアイコンで保存します。
サウンドウェーブ上を右クリックし、「キューを作成」をクリックします。
サウンドキューが作成されました。
このサウンドキューを使って音楽を再生します。
2. ブループリントを作成する
コンテンツブラウザ上で右クリックを行い、「ブループリント クラス」を選択します。
表示されるクラス選択ウィンドウで、「Actor」を選択します。
ブループリントが作成されました。
3. ブループリントに、コンポーネントを追加する
コンポーネントとは、そのブループリントが持っておくべき要素のことです。
今回は、再生する音の要素として「Audio」、音に反応する形状の要素として「Static Mesh」を追加していきます。
作成したブループリントをダブルクリックすると、専用のウィンドウが開かれます。
ウィンドウで、ビューポートタブになっていることを確認します。
左側のコンポーネントパネルから、「+追加」ボタンを押します。
コンポーネントの検索欄で「Audio」と入力し、Audioをクリックします。
同様にコンポーネントの検索欄で「Static Mesh」と入力し、Static Meshをクリックします。
コンポーネントが2つ追加されました。
次に、コンポーネントで実装に必要な設定をしていきます。
コンポーネントパネルのAudioコンポーネントをクリックし、右側の詳細パネルのサウンド>Soundで、事前準備で作成したサウンドキューを選択します。
また、アクティベーション>Auto Activeのチェックを外しておきます。
コンポーネントパネルのStatic Meshコンポーネントをクリックし、スタティックメッシュ>Static Meshで、音に反応させるメッシュを選択します。
今回はUEのプリセットで提供されている、球状のメッシュ「EditorSphere」を選択しています。
ここまでで、コンポーネントの作成と設定が完了しました。
4. ブループリントで、音楽を再生する
ここからノードをつなげて、処理を加えていきます。
イベントグラフタブに切り替えます。
「On Audio Playback Percentにイベントをバインド」ノードを作ります。
中央のグラフ上で右クリックし、「On Audio Playback Percentにイベントを割り当てる」をクリックします。
自動で「On Audio Playback Percent イベント」が作成されます。
「On Audio Playback Percent イベント」は、音楽が再生されている間繰り返し実行されるイベントで、音楽の進行度合いをパーセンテージで計算できます。
(パーセンテージの部分は今回は使いません。)
先ほど作成したAudioコンポーネントを参照するようにします。
左下のマイブループリントパネルから、変数>Audioを、イベントグラフ上にドラッグ&ドロップし、「Get Audio」をクリックします。
「Play」ノードを作ります。
音楽を再生するノードです。「ターゲット」で、再生したい音楽を指定できます。
ノードを画像のようにつなげます。
ここまでで、ゲーム開始後に
- 音楽が再生されている間、繰り返し実行されるイベントを登録する
- 音楽を再生する
ように、実装できました。
次に、繰り返し実行されるイベントとして、「再生中の音楽に応じて、オブジェクトのスケールが変わる」を実装していきます。
5. ブループリントで、Transformを動的に変化する
「Get Cooked Amplitude Envelope Data」ノードを作ります。
再生中の振幅データを取得するノードです。「Out Envelope Data」で、振幅を渡すことができます。
「Set Relative Transform」ノードを作ります。
位置、回転、スケールの情報を持ったTransformの情報を、「ターゲット」につながっているオブジェクトに対して設定するノードです。
位置、回転、スケールに分けるため、「New Transform」上で右クリックし、「構造体ピンを分割」をクリックします。
今回は、スケールを変えてみようと思うので、「New Transform Scale」の上で右クリックし、さらに「構造体ピンを分割」をクリックします。
「Get Relative Transform」ノードを作ります。
「ターゲット」につながっているオブジェクトの現時点のTransformの情報を、取得するノードです。
こちらも位置、回転、スケールに分けるため、「Return Value」上で右クリックし、「構造体ピンを分割」をクリックします。
今回は、スケールに振幅データをつなげて、音に応じてスケール全体が変わるようにしてみます。
ノードを画像のようにつなげます。
位置と回転は変化させるつもりがないので、「Get Relative Transform」のLocationとRotationは、そのまま「Set Relative Transform」のLocationとRotationにつないでいます。
ここまでで、
- 再生中の音楽(の振幅)に応じて、スケールが変わる
- 上記は、イベントとして登録されているため、音楽の再生中に繰り返し実行される
ができました。
保存して、シーンビューで確認してみます。
コンテンツブラウザにある作成したブループリントを、シーンビューにドラッグ&ドロップします。
上部の再生ボタンを押します。
残念ながらgifファイルのために、音との同期は伝えられないのですが
音の大きさに合わせて球のスケールが変化しています。
ここまでは、スケールを変化させましたが、同様に位置と回転を変化させることもできます。
上述した「構造体ピンを分割」「構造体ピンを再結合」を使って、変化させたい値に振幅のデータをつなげるだけです。
例えば、下記のようにすれば、高さ(Z)の位置のみを変えるようにできます。
変化の度合いの強弱を調整したい場合は、乗算ノードが便利です。
乗算ノードの下のボックスに値を入力すると、乗算が行われます。
高さ(Z)の位置のみを変えたものは、下記になります。
以上が、音に応じてオブジェクトの位置、回転、スケールを変化させる方法でした。
おわりに
前編では、音楽に応じてオブジェクトの位置、回転、スケールを変化させる方法をご紹介しました。
このやり方では音楽全体の振幅データを使っているため、特定の周波数や楽器に応じて変化していませんが、理想は周波数や楽器に応じて表現を変えられることだと思います。
例えば、周波数を解析して、周波数ごとにオブジェクトのTransformを変化させることができれば、オーディオビジュアライザーが作れます。
このような表現の幅が広がるような学習をしていき、今後ご紹介していければと思います。
後編では、音に応じて動的にマテリアルを変更する方法をご紹介します。
現在、電通総研はweb3領域のグループ横断組織を立ち上げ、Web3およびメタバース領域のR&Dを行っております(カテゴリー「3DCG」の記事はこちら)。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください!
私たちと同じチームで働いてくれる仲間を、是非お待ちしております!
電通総研採用ページ
使用した音のデータ:https://pixabay.com/ja/sound-effects/grinder-drum-loop-6697/
参考:https://youtu.be/nTCboJrkI8o
執筆:@iida.maya、レビュー:Ishizawa Kento (@kent)
(Shodoで執筆されました)