0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UE5 + ADX for UEで、大量のキャラクターが出るゲームのサウンドを制御する

0
Last updated at Posted at 2026-08-13

はじめに

ADXアンバサダーとして記事を書いておりますSigと申します。

この記事ではアンリアルエンジン5とサウンドミドルウェア「ADX for UE」を連携させ、大量のキャラクターやユニット、敵などが同時に音を鳴らすシチュエーションでのサウンド制御を扱います。

いわゆる無双系やVampire Survivors系のゲームのように、画面上に数十~数百の敵が同時に出現するゲームでは、攻撃音や被弾音、敵の死亡音などが一度に大量に発生します。

ADXにはシステム全体の同時発音数の上限(ボイスプール)があり、デフォルトでは72音が上限です。72と聞くと余裕があるように思えますが、大量の敵が出るゲームではあっという間に埋まります。

同時(同フレーム)に大量のサウンドが再生されるという事態を避けても、効果音にはある程度の長さがあります。同時に発音されている数となると、意外とあっさり消費してしまうものです。

そして重要なのが、デフォルトでは先着順で枠が埋まり、枠がなければ新しい音は鳴らないという挙動です。古い音が押し出されるのではなく、古い音の再生が終わるまで枠を占有し続けます。断末魔のように再生時間の長い音が大量に発生すると、枠が長時間占有され、その間は他の音が一切鳴らなくなります。

たとえば、以下のようなことが起こり得ます。

  • 敵の断末魔がボイスプールを埋め尽くし、プレイヤーが攻撃しても攻撃音が出ない
  • ボス登場のジングルが、大量のエフェクト音に枠を取られて再生できない
  • レベルアップ音やUIのフィードバック音が戦闘の真っ只中に鳴らない

本来再生されるはずのサウンドが聞こえないと、プレイヤーにとっては「攻撃したのに手応えがない」「レベルアップしたのに気づかない」という形でユーザビリティやプレイフィールに影響が出ます。

ADXのボイスリミットグループプライオリティ機能を使うと、「攻撃音は最大4つまで、断末魔は最大8つまで再生し、レベルアップなどの音は絶対に残す」といった制御ができるようになります。

当記事ではUE5.7 及び 「ADX LE UE SDK(2.05.01)」を使用します。

また、基本的にブループリントのみでの実装を行います。

ADX for UEはインディー向けの「LE版」であれば、無料で使用できます。

前提

「ADX for UE LE」を使用します。導入や簡単な使い方は以下の記事にあります。

ADX for UEの導入で、一歩上のサウンド表現を(導入編)

ADX for UEの導入で、一歩上のサウンド表現を(実践編)

実装

問題を再現する

まずは「制御しないと何が起きるのか」を確認してみましょう(ここは読むだけでもOKです)。

サンプルのサウンドを用意する

AtomCraftで以下のようなキューを用意します。

  • SE_Attack : プレイヤーの攻撃音
  • SE_Hit : 敵の被弾音
  • SE_Down : 敵の死亡音
  • SE_Item : アイテム取得音
  • SE_Lvup : レベルアップ音

A01.png

マテリアルを選択し、キューシートにドラッグ&ドロップすることでそれぞれのキューを一括で作ることができます。
A02.png
マテリアル個数ぶんのキューが作られました。
A03.png
3D空間上に鳴ってほしいサウンドはインスペクターにて、パンタイプを「3Dポジショニング」にしておきます。
この設定はUE5側で、Attenuationを設定することでも上書きできます。
A04.png
ひとまずキューシートをビルドします。
A05.png
A06.png

UEにインポートする

ビルドしたacbファイル、acfファイルをUE5のコンテンツドロワーにドラッグ&ドロップしてインポートします。

その際に表示されるダイアログでは「Yes」を選択します。これにより、プロジェクトへ自動的にAtom Configが設定されます。
B01.png
Atom ConfigとAtom Cue Sheetのふたつのアセットが作られます。
B02.png

大量のサウンドを同時に鳴らす

UE5側で、簡易的なテスト環境を作ります。

レベルに大量のサウンドをスポーンする処理を書きます。
レベルブループリントを開きます。
B03.png
カスタムイベントを作ります。
プレイヤーキャラクターの周囲のランダムな座標に、ランダムなキューを再生するイベントです。
B04.png
これをSet Timer by Eventノードで繰り返し発火します。
Timeにはゲーム内で鳴るであろう頻度を想定して入力すると挙動が確認しやすいと思います。
画像では「0.003」となっていますが、これは相当極端な例になります。
B05.png

この状態で、ランダムな音を同時に鳴らしてみます。

効果音によっては凄まじい音が鳴るので、試す際は必ず音量に注意してください!

コンソールコマンドで、「atom.3dVisualize.Enabled 1」コマンドを入力すると再生中のサウンドが可視化されます。

B06.png
B07.png

ADX for UEのパフォーマンス確認ツールである、Atom Statisticsでも確認してみましょう。
Atom Staticticsを起動するには、画面下の「Atom」から「View Runtime Statistics」を選択します。
B08.png
「Atom Statistics」が開きます。最大発音数が72であり、その枠をすべて使い潰していることが分かります。
B09.png

敵の音がボイスプール(72枠)を埋め尽くしている間、プレイヤーの攻撃音やレベルアップ音などが再生されない現象が確認できます。特に断末魔のように再生時間の長い音が大量に発生すると、枠が長時間占有され続け、その間は他の音がまったく鳴らなくなります。

ボイスリミットグループとは

ボイスリミットグループは、「同じグループの音は同時に最大N個までしか鳴らさない」という制限をかける仕組みです。

グループごとに枠を分割して確保することで、「敵の音がいくら大量に発生しても、プレイヤーの攻撃音用の枠は侵食されない」という設計ができます。デフォルトでは72枠を全キューが先着順で取り合うため、特定のグループの音が枠を占有して他の音が鳴らなくなるという問題が起きます。
ボイスリミットグループで枠を分けておけば、この問題を防ぐことができます。

併せてプライオリティ(優先度)を設定することで、同じグループ内で上限に達した際、どの音を残すかをコントロールできます。

AtomCraftでVoice Limit Groupを設定する

ボイスリミットグループを作成する

AtomCraftのプロジェクトツリーから、ボイスリミットグループを追加します。
「ボイスリミットグループ」を右クリックし、「新規オブジェクト」→「ボイスリミットグループの作成」です。
C01.png

今回は以下のようにグループを分けました。

  • VoiceLimitGroup_PlayerSE: プレイヤー関連
  • VoiceLimitGroup_EnemySE: 敵関連
  • VoiceLimitGroup_UI: UI音

C02.png

また、各ボイスリミットグループを選択し、インスペクターでボイスリミット数を設定します。これはそのグループが同時に鳴らせるサウンドの最大数です。

例として、このように設定しました。

  • VoiceLimitGroup_PlayerSE: 上限 4
  • VoiceLimitGroup_EnemySE: 上限 8
  • VoiceLimitGroup_UI: 上限 2

C03.png

上限数の決め方に正解はありませんが、目安としては「同時に鳴っても違和感のない最大数」を意識するといいかもしれません。敵の被弾音が同時に20個鳴っても、プレイヤーにはせいぜい数個分しか耳に残りません。

キューをボイスリミットグループに割り当てる

各キューに含まれているウェーブフォームを選択し、インスペクターでボイスリミットグループを指定します。

C04.png

  • SE_Player_Attack: VoiceLimitGroup_PlayerSE
  • SE_Enemy_Damaged: VoiceLimitGroup_EnemySE
  • SE_Enemy_Death: VoiceLimitGroup_EnemySE
  • SE_Item_Pickup: VoiceLimitGroup_PlayerSE
  • SE_LevelUp: VoiceLimitGroup_UI

C05.png

これで、敵の音がいくら大量に発生してもプレイヤーの攻撃音用の枠は食われなくなります。

プライオリティを設定する

同じボイスリミットグループ内で上限に達したとき、どの音を残すかを決めるのがプライオリティです。

インスペクターでプライオリティ値を設定します。優先したい音の値を上げるといいでしょう。

C06.png

上限到達時の挙動を設定する

Voice Limit Groupには、上限に達したときの挙動も設定できます。

  • 後着優先 : 新しい音を優先し、古い音を止める
  • 先着優先 : 既に鳴っている音を優先し、新しい音を鳴らさない
  • Priority比較 : Priority値で比較し、低いほうを切る

プレイフィールを見てみると、敵のSEは「後着優先」が自然なことが多いです。常に新しい敵が迫ってくるので、「古い敵の音がいつまでも居座る」より「目の前の敵の音が優先される」ほうが直感と合いそうです。

キューシートをビルドし、UE5に再インポートします。

UE5で動作を確認する

先ほどのテスト環境で、Voice Limit Group適用後のサウンドを確認します。

再度PIEを起動し、大量の敵が音を鳴らす中でプレイヤーの攻撃音やレベルアップ音を鳴らしてみましょう。

サウンドの発音数が制限され、挙動も設定したとおりになっていれば成功です。

C07.png

距離に応じたPriorityの動的変更

ここまでの設定でも十分機能しますが、もう一歩踏み込んでみます。

ゲーム内では画面の端の敵より、プレイヤーの目の前の敵の音のほうが重要です。プレイヤーとの距離に応じてPriorityを動的に変える実装を追加してみます。

距離を取得する

サウンド再生の前にプレイヤーとの距離を計算します。

プレイヤーの位置とサウンドの再生位置を比較し、Vector Lengthノードで距離を取得します。

D00b.png

距離をプライオリティに変換する

距離が近いほどプライオリティが高く、遠いほど低くなるように変換します。最大距離を決めてその中での割合を変換させる計算です。

例: 最大距離を2000とした場合

  • 距離 0(目の前): プライオリティ最大
  • 距離 2000(遠方): プライオリティ最小

Map Range Clampedノードを使うと、値の範囲変換を簡潔に書けて便利です。

D00.png

Spawn Sound時にプライオリティを渡す

算出したプライオリティ値を、サウンドスポーン時に渡します。

D01.png

まとめ

大量の敵が出現するゲームでのサウンド制御を、ボイスリミットグループとプライオリティで制限・調節してみました。

この仕組みは大規模なRTSなど、多数のユニットが同時に存在するジャンル全般に応用できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?