Unity
Sound
Adx2
ADX2LE

Unityでインタラクティブミュージック with ADX2 基礎編

ゲームにインタラクティブミュージックを実装しよう

ゲームを遊んでいるとき、ゲームの展開に合わせて音色が変化するBGMについて気が付いたことがありますか?

通常、ゲームのBGMとは3分や5分など決まった時間の素材をループすることで実現します。よくあるゲーム的な演出としては、曲の「イントロ」と「ループ部分」を分けたデータにしておき、曲のなり始めだけにイントロを再生する手法もよく使われますが、そちらの解説は次回にて。

さて、「インタラクティブミュージック」はゲームプレイの内容に応じて鳴っている曲をリアルタイムに変化させる手法をさします。
ボス戦で簿図の体力が減ってきたときに派手な楽器の音を加える、体力が薄くなってきたときに不穏な音を加える、プレイヤーキャラがマップを移動したとき、に土地柄に合わせた楽器を入れる...など、ゲーム内のトリガーにあわせて曲を変化させます。ステージの終盤で曲が早回しになるのも一種のインタラクティブミュージックですね。
(細かくは、ユーザーの入力によって直接的に変わるものをインタラクティブミュージック、ステージ変化などのゲーム側の演出で変わっていくものをアダプティブミュージックと呼んだりもします。)

どのようなものを「インタラクティブミュージック」と呼ぶかは諸説ありますが、ここでは「ゲーム内容の状況に合わせて変化する楽曲」とします。

さらに詳しくはじーくどらむす氏のこちらの投稿に詳しいです。

「インタラクティブミュージック」という、ゲームと音楽の関係性

最近の事例ですと、「オクトパス トラベラー」がインタラクティブミュージックを積極的に取り入れていました。
本作はRPGなのですが、特定のボス戦時のみ、フィールドマップから戦闘シーンに移るシーンで楽曲がシームレスに変化します。

http://jp.gamesindustry.biz/article/1810/18101501/

ゲームの進行と連動した音楽の演出はプレイの盛り上がりや焦りを与えることができ、うまくつかえば最高に「アガる」演出になります。
では、Unityを使った自作ゲームでこうしたインタラクティブミュージックを導入するにはどうしたらいいでしょう?

ADX2 for Unityについて

インタラクティブミュージックはUnity 標準のオーディオ機能でもできなくはないですが、サウンドの知識があまりないプログラマーでもなるべく手間を省いて実装できるよう、CRI ADX2を使います。

統合型サウンドミドルウェア・ADX2
https://game.criware.jp/products/adx2-smartphone/

理由は次の通りです。

  • Unity標準システムだと厳密なタイミング制御が難しい
    音をサンプル単位で管理する必要があるのですが、Unity標準機能では難しいです。
    もちろん自前でやろうとすると制御用のコードを大量に書く必要があります。

  • マルチトラック(複数音の同時再生)を行うとCPU負荷が高い
    Unityの標準機能や、その他のサウンドツールでは圧縮コーデックにOgg Vorbisを使っています。大量に音を鳴らす場合でさらにマルチトラックの再生となるとCPU負荷が高くなってしまいます。
    「ADX2」にはゲーム専用のコーデックとして「HCA」「HCA-MX」を搭載していますので、CPU負荷を気にしなければいけない場面では有利です。(特にモバイル端末、Android端末では実績が多いです。)

本エントリーは、ADX2をUnityに導入する手順や用語について詳しくは述べていません。はじめてADX2 / ADX2 LEを触る方は、前章の「Unity 2018のサウンド機能をADX2で強化する」をご確認ください。

開発中ゲーム「デモリッション ロボッツ K.K.」デモ版のインタラクティブミュージック

こちらです。4人対戦ゲームですのでSEをバンバン鳴らしつつCPU負荷を抑えたかったのと、ダウンロードタイトルなので容量を小さくするためにADX2を導入しています。
先日行われたイベント「デジゲー博 2018」でプレイアブル展示を行ったのですが、このデモ版にて簡易的なインタラクティブミュージックを実装しました。

インタラクティブミュージックは、前述のオクトパストラベラーのようにある曲から別の曲へ「つなぎ曲」を挟みつつダイナミックに変化するものもありますが、今回は一番簡易的な「DAWからトラック別に音源を出力し、ミックスをリアルタイムに変化させる」という手法を取っています。

DAWによる作曲とトラック別の出力

普段のゲーム用作曲ではGarageBandを使っていまして、いまREAPER勉強中なのですが、今回はあまり時間が取れなかったので、iOS向けアプリの「Figure」を使ってループ曲を作り、AIFFファイルに出力してからADX2ツールに読み込ませ、ゲームに組み込んでいます。

figure.png

「Figure」はDAWツールの「Reason」を開発しているPropellahead社が開発したアプリです。手軽にループ曲が生成でき、高品質です。(現在は音楽SNS Allihoopaに移管された模様)

Figure mix

曲を「DRUM」「BASS」「LEAD」の3トラックで制作できる簡易ツールなのですが、出力時にトラックを個別にMUTEできます。この機能を使って、曲を作ってからトラック別に3つのAIFFを出力しています。

今回はパリピ感のある音源を使ってパーティっぽい感じの曲を作りました。

Demolition Robots K.K. 2018 Demo Battle BGM.png

QiitaはSoundcloudの埋め込みができないみたいなので、こちらから。音量注意。

「Battle」が3つのトラックをミックスしたもの、only~の3つがバラの音源です。
たぶんこのゲームの製品版には正式利用されないので、テスト用にダウンロードして使ってもOKです。

他のDAWツールを使う場合も、同じようにトラックごとにWAVEやAIFFに出力すればOKです。タイミングはそろっていると楽ですが、難しい場合はあとでADX2のツール側でそろえることもできます。

ADX2ツールへの読み込みと再構成

さて、トラック別に出力した3つの波形データをADX2のツール上で再構成します。
上記ゲームでは製品版「ADX2」を使っていますが、今回は無償版の「ADX2 LE」で同じことをやってみています。

キューの作成.png

まずはADX2のCRI Atom Craftを使って、今回使用するキューシートの下にBGM用のキューを作成します。今回は「Battle」としておきます。
キューシート「CueSheet_0」を選択して右クリックからキューを新規作成します。このとき、右に表示される空のキューにて再生方法が「ポリフォニック」になっていることを確認してください。
キューを再生したとき、すべてのトラックが同時に再生されることを意味します。

3つのマテリアルをBattleキューにドラッグ.png

次に、3つのトラックをBattleキューの中にドラッグして、曲を再構成します。
それぞれの音量は波形表示の左隣にある青いバーで調整できます。
F5キーを押してキューのプレビュー再生を行い、3つのトラックが同時に再生されることを確認してください。

ゲーム内の何を基準に曲を変化させるか考える

「デモリッション ロボッツ K.K.」は、ロボットが街を破壊していくゲーム内容です。
そのためステージBGMの変化は、街中のビルの残数によって変化する、としました。
ゲーム開始直後はおとなしめで、ビルの数が減ってくるとだんだん盛り上がってくるイメージです。

2.png

本作ではUniRxを導入しており、「どのビルがどのロボットに破壊されたか」という情報を流すストリームを走らせて各制御を行っているのですが、その値の発行をフックしてビルが壊されるごとに「いま全体で何パーセント壊されたか」という値を算出し、0f~1fのfloat値をADX2側へ渡しています。

ADX2ツール側のインタラクティブミュージック設定

さきほど作った3つのトラックを持つキューについて、ボリュームのバランスをゲームから動的に変化させる仕組みを作ります。
ADX2のもつ「AISAC」という機能を使います。

Advanced Interactive Sound and Active Controllerの略
AISACコントロール値に対応するボリュームやピッチ、フィルタ等のカーブを作成して音色を変化させたりする機能。
例えば、あるキャラクターとの距離をコントロール値とし、その距離に応じたキャラクターのセリフ音量のカーブを描いておくことで、距離に応じた音量をデザインすることができます。

http://blog.cri-mw.co.jp/adx2portal/glossary/#aisac

「コントロール値」と言っているのが、ゲームから発行してADX2側で受ける制御用の数値のことです。
今回の例では、「どのくらいのビルが破壊されたか」という割合の値になります。
「音量のカーブを描く」とありますが、与えられた値に応じて各トラックの音量をどう変化させるかをADX2内で設定していきます。

Atom Craftでさきほど設定した「Battle」キューのうち、ひとつトラックを選択して右クリックから「新規オブジェクト」→「AISACの追加」をクリックします。

aisacの追加

次のようなダイアログが出ます。
「AISAC名」はトラックごとのAISAC設定の名前、AISACコントロールIDは、プログラムから値を通知するときに指定する名前です。
AISACグラフタイプは操作する音の要素を指定する部分になります。今回は「ボリューム」です。

3つのトラックの音量を同時に操作したいので、AISACコントロールIDが3つのトラックとも同じである必要があります。
デフォルトでは「0:Any」になっていますので、これを指定して「追加」をクリックします。
(Atom Craftのバージョンによっては、Aisac名が「AisacControl_00」になっていることもあります。)

AISACの追加

すると、波形の下部に黄色い線が表示されます。これがAISACコントロール値です。

aisacコントロール.png

横方向の0から1までの値が、Unityから与える数値を示しています。キューの再生を行いながらツール内で白い棒を左右に動かすとプレビューができます。

aisac棒.jpg

まだボリューム変化を何も設定していないので、変化は起きません。
このグラフをクリックするとポイントができ、マウスでドラッグすることでカーブを作成できます。

ここで、各トラックの名称をそれぞれ「Bass」「Drum」「Lead」に変えておきます。どのトラックを操作しているかわかりやすくするためです。
3つのトラック全てにAISACの追加が終わったら、カーブを設計していきます。
例として次のようにボリュームの変化を作りました。

ボリューム変化の設定

特に理論だったものはないですが、はじめはBassの音だけ聞こえており、数値が上がるにつれてBassは小さくなりDrumとLeadの音量が上がってきて、終盤はDrumが下がりLeadの主張が大きくなる...という設定にしてみました。
(Leadは「プアープアー」というパリピ感の強い音源にしているので、終盤っぽさがでるかなと....)

なめらかなカーブを作る機能も追加されています。

カーブのタイプ.jpg

ポイントの上で右クリックすると、曲線のタイプを選ぶことができます。

さいごに、プログラムからこのコントロール値を呼び出しやすいよう、AISACコントロールIDの名前を変えておきます。

Atom Craft左上の「プロジェクト全体設定」に現在のAISACコントロール値の一覧があります。
先ほど3つのトラックのAISACコントロール値を「Any」に設定したと思いますが、これを判別しやすい名前に変更します。

今回はBGMのミックスを変化させるので、「BgmMixControl」という名前にしてみました。

AISACコントロール値の名前の変更.jpg

ここまでできたら、キューシートバイナリをビルドしてUnity Editorにビルドされたデータをコピーします。
(再度注 本エントリーは、ADX2をUnityに導入する手順や用語について詳しくは述べていません。はじめてADX2 / ADX2 LEを触る方は、前章の「Unity 2018のサウンド機能をADX2で強化する」をご確認ください。)

Unity側でAISAC値をコントロールする

Unityでゲームを実行中に、AISACの値を変化させる手順は非常に簡単です。
AISACを設定しているキューを再生中のAtomSourceコンポーネントに対し、SetAisacControl関数で指定します。

Adx2Controll.cs
public CriAtomSource bgmCriAtomSource;

public void SetValueToBGMAISAC(flaot aisacValue)
{
 bgmCriAtomSource.SetAisacControl("BgmMixControl", aisacValue);
}

なお、ADX2のバージョンによってはAisac値が初期化されていなかったり0fが入っていたりするとAisac設定どおりのなり方をしない場合がありますので、その際は再生開始時にfloat.Epsilonを与えてあげるとよいでしょう。

設定は以上です。実際にUnity Editor上で曲を鳴らしながら、狙い通りの変化になるようAtom Craft上でグラフの調整を行っていきましょう。