はじめに
ADXアンバサダーのSigと申します。
アンリアルエンジンとサウンドミドルウェア「ADX for UE」を連携させ、「オブジェクトごとに『スポーン時』『衝突時』などに個別の効果音を手軽に設定する」実装を行います。
前提
当記事ではUE5.0を使用しています。基本的にブループリントのみでの実装を想定します。
ADXはインディー向けの「LE版」であれば、無料で使用できます。
https://game.criware.jp/products/adx-le/
なお、ADX2は「ADX」へ名称が変更になりましたが、ツール構成は変更ありません(2がないから古いほう、というわけではありません)。
記事執筆時点のADX for UEのSDKバージョンはADX LE UE SDK(1.31.00.01)です。
ADX for UEの導入や基本的な使い方は以下の記事にあります。必要に応じて参照してください。
ADX for UEの導入で、一歩上のサウンド表現を(導入編)
ADX for UEの導入で、一歩上のサウンド表現を(実践編)
実装
AtomCraftで様々な効果音を用意する
AtomCraftを使い、UEに持っていくためのサウンドを構成します。
マテリアルの用意
まずは素材となるサウンドを用意し、マテリアルとしてAtomCraftにインポートします。
音源ファイルをマテリアルツリーにドラッグ&ドロップしましょう。
今回はオブジェクトの「スポーン時」「破壊時」「衝突時」「被ダメージ時」それぞれに効果音を用意します。
オブジェクトA,B,Cにおいて、3タイプの効果音を一通り準備しました。
また、それぞれのオブジェクトごとにフォルダ分けをしています。
キューの作成
効果音ごとにキューを作成します。
「新規オブジェクト」→「キュー『ポリフォニック』の作成」を選択してキューを新規に作成します。
キューに名前をつけます。
……という流れでもいいのですが……!
効果音単体のキューを作る場合、マテリアルツリーからドラッグ&ドロップするだけでキューが完成します。
シンプルなキューができました。
複数選択してドラッグ&ドロップすることで、一気にキューを作っていくことができます。
お手軽にキューを量産できました。
距離減衰をUE内で実現するため、キュー内の「パンタイプ」を「3Dポジショニング」に設定します。
キューシートのビルド
UEで効果音を設定・再生する
キューシートのインポート
ビルドしたacbファイル、acfファイルをUEのコンテンツブラウザの任意の場所にドラッグ&ドロップしインポートします。
すべてのキューが正しくインポートされていることを確認します。
ツールバーの「Edit」→「Project Settings」からプロジェクト設定を開き、
「CriWare」タブ、Atom Configの項目に今回インポートしたacfファイルを指定します。
構造体を作成・設定する
オブジェクトごとに手軽に効果音を設定するために、「どの状況でどの効果音を鳴らすか」というテンプレートが欲しいところです。そこで、規格となる構造体(Structure)を作成しましょう。
コンテンツブラウザの任意の場所で右クリックし、「Blueprints」→「Structure」を選択。
構造体(Structure)が作成されました。
ダブルクリックして開きます。
変数に名前をつけ、型を「Sound Atom Cue」→「Object Reference」に設定します。
「+Add Variable」ボタンを押し、変数を追加します。
新たな変数に名前をつけます。型が「Sound Atom Cue」になっていることを確認しておきましょう。
「SpawnSound」「DamageSound」「HitSound」「DestroySound」を追加します。
これで、この構造体は4つの変数を内包するようになりました。
あとはこの構造体をBPアクター側から分解し、取得して再生するだけです。
構造体のパラメータを参照して再生する
オブジェクト側の処理を書いていきます。
コンテンツブラウザの任意の場所でアクターを作成します。
「Blueprint Class」を選んで作成します。
親クラスは「Actor」とします。
作成されたアクターに名前をつけます。このアクターをベースとして、様々な見た目や効果音にカスタマイズします。
ダブルクリックして開きます。
「StaticMesh」コンポーネントを作成します。
「StaticMesh」コンポーネントには、仮のモデルとマテリアルを指定しておきます。
イベントグラフに移動します。
変数を新規に追加します。
変数に名前をつけます。
Variable Typeには先ほど作って設定した「Str_ObjectSound」を選択します。
コンパイルすると、Atom Cueが設定できるようになります。
仮として、デフォルトのサウンドを設定します。
「Instance Editable」にチェックを入れ、外部から編集可能にしておきます。
レベル上でビューポートから個別にサウンドを指定できるようになります。
イベントグラフに処理を書いていきましょう。
構造体からの値は、Get (構造体名)ノードから線を伸ばし、Break (構造体名)ノードで取得できます。
サウンドの再生はSpawn Atom Sound at Locationで行います。
これだけで、スポーン時のサウンドが再生できます。
衝突時のサウンドを再生するため、StaticMeshコンポーネントの「Simulate Physics」にチェックを入れ、物理挙動をONにしておきます。
StaticMeshアクターの「Add Event」から、「Add On ComponentHit」を選択。
衝突時のイベントが作られるので、そこからサウンドの再生を行います。
Break Str_ObjectSoundノードからの参照は「HitSound」です。
また、Event AnyDamageイベントから「DamageSound」を再生し、
Event Destroyedイベントから「DestroySound」を再生すればOKです。
これで、スポーン時や衝突時、被ダメージ時やデストロイ時にサウンドが再生されるようになりました。
サウンドの再生を確認するには、コンソールコマンド「cri.ShowSoundLocation 1」で視覚化できます。
レベル上のアクターを複製し、Detailsパネルから「ObjectSoundList」を編集すれば、再生するサウンドを変更できます。
また、Detailsパネルの「StaticMesh」コンポーネントを選択すると、メッシュの見た目やマテリアル、各種物理パラメータなどが個別に設定できます。
こちらも再生して、挙動が正しいことを確認してみましょう。
こうして、シンプルなオブジェクトとその物理挙動、またその際のサウンド再生が手軽に再生できるようになります。
ゲームのステージ上に配置し、世界観を盛り上げる小道具として役立ちそうです。
今回作成したアクターはごくごくシンプルな構造をしていますので、カスタマイズの余地が大幅にあります。
このクラスを継承して新たな機能を持つアクターを作ってもいいですし、また構造体をデータテーブルに登録して外部のスプレッドシートから音源を取得することも可能です。