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で、キャラクターの「溜め行動」に応じてサウンドを変化させる

Last updated at Posted at 2023-04-27

はじめに

ADXアンバサダーとして記事を書いておりますSigと申します。
この記事ではアンリアルエンジン5とサウンドミドルウェア「ADX for UE」を連携させ、ゲーム内でプレイヤーがボタンを押している時間に応じて、アクションのサウンドが変化する実装を紹介します。
ゲーム内でキャラクターが「溜める」(チャージする)行動をとった際にチャージ用効果音が段々と変化し、その後のアクションのサウンドにも影響を与えます。

アクションゲームによくある演出ですね。
チャージしている間の無防備な瞬間の緊張感と、発射した瞬間のカタルシスを表現するのに役立つ表現です。

実装の概要はこんな感じになります。

  • 特定のボタンを長押しすると、キャラクターがチャージを開始する
  • チャージ音は最初は低い音で、溜め続ける(ボタンを押し続ける)ことで段々高く音が変化する
  • ボタンを離すとチャージが終了し、キャラクターがチャージショットを発射する
  • アクションの開始と同時にサウンドが再生され、さらにチャージ段階によって変化する

チャージ中のサウンドはAISACコントロールで操作し、チャージショットに関してはゲーム変数による「スイッチ」機能で実装します。

当記事ではUE5.5+「ADX LE UE SDK(2.01.00)」を使用します。
また、基本的にブループリントのみでの実装を行います。
ADX for UEはインディー向けの「LE版」であれば、無料で使用できます。
https://game.criware.jp/products/adx-le/

前提

「ADX for UE LE」を使用します。導入や簡単な使い方は以下の記事にあります。
ADX for UEの導入で、一歩上のサウンド表現を(導入編)

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

実装

AtomCraftでチャージ音、アクション音を構成する

マテリアルのインポート

必要になるサウンドを用意し、インポートします。
今回用意したのはチャージ中に再生され続ける「SE_Charge」、そしてチャージ段階に応じた3種類のチャージショット音「SE_ShotA,B,C」です。「SE_Charge」はループできるものがいいでしょう。
A01.png

マテリアルツリーで「SE_Charge」を選択し、ループ情報の上書きを「True」、ループタイプを「ループ」にします。
これで自動的にループ再生され続けるようになります。
A02.png

チャージ用キューの構成

新規にキューを作成します。
ワークユニットツリーでキューシートを右クリックし、「新規オブジェクト」→「キュー『ポリフォニック』の作成」を選択します。わかりやすいよう名前もつけておきます。
A03.png

マテリアルツリーから「SE_Charge」をドラッグアンドドロップして配置します。
テスト再生し、ループ再生されることを確認します。
A04.png

トラックリストの空欄で右クリックし、「新規オブジェクト」→「AISACの作成」を選択します。
A05.png

名前をつけ、AISACグラフタイプを「ピッチ」にします。チャージが長くなるにつれどんどん音が高く、早くなるイメージです。
A06.png

「ピッチ」のグラフを選択し、グラフを右肩上がりになるよう編集します。
A07.png

テスト再生しながらスライダーを動かし、サウンドがどのように変化するのか試してみましょう。
チャージを開始した瞬間は左端の部分が流れ、チャージ段階が最大になると右端のように再生されます。
A08.png

チャージショット用キューの構成

チャージショット用のキューを作成します。
ワークユニットツリーでキューシートを右クリックし、「新規オブジェクト」→「キュー『スイッチ』の作成」を選択します。
A09.png

キュー内に3つのサウンドをトラックを分けて入れておきます。
A09b.png

再生し分けるために「ゲーム変数」を追加します。
プロジェクトツリーで右クリックし、「新規オブジェクト」→「ゲーム変数の作成」を選択します。
A10.png

新しいゲーム変数に名前をつけます。今回は「ChargeLv」としました。
A11.png

チャージショットのキューを選択し、インスペクターにて「スイッチ」を開きます。
A12.png

スイッチ変数に新しく作成した「ChargeLv」を設定します。
A13.png

「等分化」ボタンを押し、各スイッチ幅が均等になるようにします。
A14.png

「セッションウィンドウ」でどう再生されるか確認してみましょう。
A15.png

ドラッグ&ドロップでセッションウィンドウにテストしたいキューを追加します。
「ゲーム変数」ボタンを押すと、テスト用のゲーム変数が編集できるようになります。
A16.png

ゲーム変数「ChargeLv」を動かし、数値によってサウンドが変化することを確認してください。
A17.png

キューシートのビルド

ここまでできたら、キューシートをビルドしてUEに持っていきます。
A18.png

A19.png

UEでサウンドを実装する

キューシートのインポート

ビルドしたacbファイル、acfファイルをコンテンツドロワー(コンテンツブラウザ)にインポートします。
acfファイルのインポート時に出てくるダイアログでは「Yes」を選択します。
これにより、プロジェクトにAtom Configが適用されます。
B01.png

キューシートが正常にインポートされたことを確認します。
B02.png

入力の登録

チャージショットアクションの入力用ボタンを登録します。
コンテンツドロワー(コンテンツブラウザ)の適当なところで右クリックし、「Input」→「Input Action」を選択してInput Actionを作ります。
B05.png
また、入力ボタンをまとめた「Input Mapping Context」が必要なので作成します。
B07.png
ふたつのアセットが作られたことを確認します。
B06.png
Input Mapping Contextを開き、Input Actionを登録します。
今回はマウスの左クリックにチャージショットアクションを割り当てました。
B08.png

サウンドの再生

キャラクターのブループリントアクターを開きます。
B09.png
Input Mapping Contextをこのキャラクターで使えるよう、Event Begin Playのタイミングで登録します。
B10.png

登録した入力を感知するイベントノードEnhancedInputAction IA_ChargeShotを追加します。
C01.png

チャージ中かどうかを判別する変数、「bCharge」を追加します。型はBooleanです。
C02.png

EnhancedInputAction IA_ChargeShotノードでは「Started」はボタンが押された時、「Completed」はボタンが離された時にトリガーされます。
それぞれ、「bCharge」の状態に応じて、ボタンが押されていれば「bCharge」をTrueに、ボタンが離されていれば「bCharge」をFalseといったように値を変動させます。
C03.png

入力処理が正しいか不安な場合は、このように簡単なテストメッセージを表示してみましょう。画面左上に、現在の「bCharge」の状態が表示されます。
C04.png

「bCharge」がTrueになったタイミングで、Spawn Sound Attachedノードを使ってチャージ用のサウンドを再生し始めます。このノードでは再生と同時に、指定したコンポーネントにサウンドが追従します。追従先はキャラクターメッシュなど、チャージサウンドが発されているものにしましょう。
C05.png

Spawn Sound Attachedノードの青いアウトプットピンを右クリックし、「Promote to Variable」で変数化します。
これにより、変数化しておいたサウンドに後から用意にアクセス可能になります。
C06.png

変数化したサウンドは「ChargeSound」と名前をつけました。
C07.png

また、何らかの理由で再生が停止されたときにコンポーネントを自動的に破棄するよう「Auto Destroy」にチェックをつけておきます。
C99.png

入力強度が0.1以上でない(つまりボタンを離している)側では、チャージ中であればチャージ状態を解除(False)にし、チャージサウンドをStop及びDestroy Componentして再生を停止します。
C08.png

また、その後またSpawn Sound at Locationノードでチャージショットのサウンドを再生します。
C09.png

現時点でのノードの全体図はこのようになります。
C10.png

この状態で最低限の機能が実装されているので、テストしてみましょう。ボタンを押している間チャージサウンドがループし、離すと再生が停止し、その代わりにチャージショットのサウンドが再生されます。

チャージに応じたチャージ音のサウンド変化

チャージ段階によりサウンドが変化するよう実装していきます。
まずはチャージ段階を記憶しておくための変数「ChargeLv」を追加します。型はFloat型です。
D01.png

ボタンを押している間かつチャージ中である場合、チャージ段階を加算していきます。今回はGet World Delta Secondsノードを加算してるため、リアルタイムの1秒でチャージ段階が「1.0」上昇します。
D02.png

ボタンを押し続けている間チャージ段階が無限に上昇してしまうので、Clampノードを噛ませて最大値を制限します。
D03.png

Set Aisac by Nameノードを使い、キューに対してAisacコントロールを行います。値は「ChargeLv」をそのまま代入します。
D04.png

しかし、ゲームの処理によってはチャージ段階が「0~1.0」の間だけとは限りませんよね。チャージ段階がどの値であってもAisacコントロールには「0~1.0」の値を渡したいため、Map Range Clampedノードを使用します。
「In Range」に入力(チャージ段階の最小値と最大値)を入れ、「Out Range」にはAisacコントロールの段階の最小値と最大値を入力します。
これにより、「Return Value」からチャージ段階に応じたAisacコントロール値用の「0~1.0」の数値が出力されます。
D05.png

チャージに応じたチャージショットのサウンド変化

チャージショットのサウンドも段階的に変化させていきます。
ゲーム変数に応じたサウンドの変化はAtomCraft側で設定したるので、ここでやるべきことはSet Atom Game Variableでゲーム変数を代入してあげることだけです。
Aisacコントロールと同じようにMap Range Clampedノードで数値を丸め、ゲーム変数に渡してあげます。
D06.png

最後に、チャージショットを撃つと同時にチャージ段階の数値をリセットします。
D07.png

これで基礎的なチャージショットのサウンドが実装できました。
実際に操作してみると、それなりにゲーム的な気持ちよさが再現できているのが分かるかと思います。

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?