ADX for Unityで、BGMに動的なエフェクトをかける

# はじめに

ゲーム開発において、プレイヤーの状況や場面によってBGMを変化させたいが、新規に曲を作るのはコストが掛かる…そう思ったことはありませんか？
特に、3D空間を自由にアクションするようなタイプのゲームの場合、様々なステージやプレイヤーの状態が存在するかと思います。その１つ１つに合わせて曲を作るのは非常に大変です。
しかし音源自体は１つでも、エフェクトを掛けることで以下のように様々な演出が可能です。

- ローパスフィルタをかけ、スローモーション演出や雨天時の屋内への移動を表現
- ハイパスフィルタをかけ、浮遊感や疾走感を表現
- リバーブエフェクトをかけ、広い洞窟のような空間を表現

本記事ではUnityとサウンドミドルウェア「ADX for Unity」を用い、ゲーム内のシチュエーションに合わせてBGMに上記のようなエフェクトを掛ける演出を実装します。

※この記事は「ADX2 for UE4で、BGMに動的なエフェクトをかける」のUnity版です。元記事作者の[Sig](https://qiita.com/SigRem )さんの許可を得て作成しています。

[https://qiita.com/SigRem/items/bd790528f4195d492795](https://qiita.com/SigRem/items/bd790528f4195d492795)

# 前提

### 動作確認環境

Windows 10 Home 20H2
Unity 2020.3.27f1  + ADX LE Unity SDK 3.06.03
CRI ADX LE Tools for Windows 3.46.09

### 前提記事

CRI ADX導入方法や基本的な操作については以下の記事を参照して下さい。

Unityのサウンド機能をADXで強化する

[https://qiita.com/Takaaki_Ichijo/items/16e6501fc07f5b3b3377](https://qiita.com/Takaaki_Ichijo/items/16e6501fc07f5b3b3377)

# やること

- AtomCraftでキューを作成
- DSPバスを設定し、エフェクトを用意
- Unityにインポート
- テストシーンを作成しリアルタイムにエフェクトのかかり方を変更する

# 実装

## AtomCraft側

まずは、再生する音データの作成を行います。ADXにおいては、再生用のデータはUnityとは別のツール「AtomCraft」を使います。
その手順については、元の記事（UE4向け記事）の同名の項と同じになりますので省略しています。本記事の手順を試す場合は、まず元の記事の[該当項目](https://qiita.com/SigRem/items/bd790528f4195d492795#atomcraft%E5%81%B4)を進めてから本記事を進めてください。
UE4版との違いとして1点、「Atomキューシートバイナリのビルド」画面で、一番左下のオプション「UnityAssets出力」にチェックを入れるのを忘れないようにして下さい。

## Unity側の実装

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

AtomCraftからエクスポートしたファイルをインポートします。

### テストシーン用のスクリプト作成

以下のスクリプトをDSPController.csとして作成します。

```DSPController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DSPController : MonoBehaviour
{
    public CriAtomSource criAtomSource;
    public string busName;

    void Start()
    {
        CriAtom.AttachDspBusSetting("DspBus_Music");
        criAtomSource.SetBusSendLevel(busName, 0);
        criAtomSource.Play();
    }

    public void SetBusSendLevel(float value)
    {
        criAtomSource.SetBusSendLevelOffset(busName, value);
    }
}
```

CriAtom.AttachDspBusSettingは引数に指定したDSPバス設定をアタッチします。
SetBusSendLevelは指定したバスセンドレベルに0-1のfloat値を乗算で設定します。
SetBusSendLevelOffsetは指定したバスセンドレベルに0-1のfloat値を加算で設定します。これはSetBusSendLevelの適応後の値を基準とするため、今回のようにsliderで特定の値にセットしたい場合はSetBusSendLevel（ないしAtomCraftでの設定）で一旦０にする必要があります。

(AtomCraftで設定したバスセンドレベル　×　SetBusSendLevelの設定値)　+　SetBusSendLevelOffsetの設定値

### テストシーンの作成

以下のようなシーンを作成します。

![テストシーン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/2eda9315-a631-0c18-769a-5e63e2cb8a8b.png)

- CriWareLibraryInitializer、CriWareErrorHandler
    - 基本コンポーネント、GameObject＞CRIWAREから作成
- CRIWARE
    - 自動生成
- Cue_DSP_Ex01(CriAtomSource)
    - 前項でインポートした音源
- Canvas
    - 重要なのはslider3つ
    - Reverb,Phaser,BitCrusherのGameObjectにはそれぞれDSPController.csをアタッチ
    - それ以外は画面とヒエラルキーの整理用

![sliderの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/5927bada-30b9-d70e-1b95-b5f54d2b1725.png)

- 各sliderのOnValueChangedにはDSPController.csのSetBusSendLevelを登録

![DSPControllerの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/1bd6b64d-ea9b-1279-7504-30a87af17bde.png)

- 各DSPController.csの設定
    - CriAtomSourceにはCue_DSP_Ex01(CriAtomSource)を登録
    - BusNameにはGameObject名（AtomCraftで設定したDSPバスの名前）を入れる

### テストシーンの実行

ここまで出来たら忘れずに保存し、実行しましょう。
スライダーを動かすと対応したエフェクトの掛かり具合が変化することが確認できます。

# 応用

今回のサンプルではポリフォニックを選択しエフェクトのみ適用しました。AISACによるコントロールを追加したり、キューのタイプを「セレクタによるトラック遷移」に変更したりすることで、より多彩なコトロールが出来るようになります。