はじめに
Unityと、サウンドミドルウェア「CRI ADX」を連携させ、ゲームの状況によって変化するBGM=インタラクティブミュージックをセットアップします。
本記事は以下の記事のUnity版です。
記事中では「ADX2 for UE4でインタラクティブミュージック(AtomCraft編)」で用意したサウンドデータ(ビルド後のファイル)を使用します。
記事はUE4向けですが、操作するツールは共通です。
ただし1点、「Atomキューシートバイナリのビルド」画面で、一番左下のオプション「UnityAssets出力」にチェックを入れるのを忘れないようにして下さい。
CRI ADX導入方法や基本的な操作については以下の記事を参照して下さい。
やること
- Unityにインポート
- Animation、Animatorでパラメータを操作
- BGMのトラックごとにフェードイン・フェードアウトができるようにする
- テストプレイ
Unityでのセットアップ
ADXプラグインを導入したUnityプロジェクトを開き、音を出せる状態にします。導入方法については、以下を参照してください。
通常再生の準備
ビルドしたキューシートをインポートし、AtomBrowserに表示されていることを確認します。「Create GameObject」で「IMLoop(CriAtomSource)」をシーン上に配置、「PlayOnStart」にチェックを入れておきます。
設定が終わったら実行し、自動的に再生されることを確認します。
AISAC値の操作
スタート地点ではBGMは鳴らず、プレイヤーのいる位置によってAパート、Bパート、Cパートと次々にフェードインする、といったインタラクティブミュージックを実装します。
テスト用フィールドの作成
今回はBGMの変化が効果的にテストできるよう、こんなフィールドを用意します。壁はコライダーをイメージしやすくするためのものなので、なくても問題ありません。
カプセル型のオブジェクトはプレイヤー代わりです。「GameObject」>「3DObject」>「Capsule」で作成、「Rigidbody」コンポーネントをアタッチしてis Kinematicとis Triggerにチェックを入れます。「Player」というTagを新規作成し設定します。(大文字小文字に注意)
A、B、Cの各パートエリアに入ったことを感知するため、BoxColliderを配置します。親となるGameObjectの名前は「Trigger_Apart」「Trigger_Bpart」「Trigger_Cpart」としておきましょう。AがB、BがCを内包するよう、各パートエリアの座標と大きさを調整します。
さらに「Animator」コンポーネントと以下の「ADXController.cs」をアタッチします。「ADXController.cs」の「bgmCriAtomSource」には「IMLoop(CriAtomSource)」を設定、「Trigger_Apart」「Trigger_Bpart」「Trigger_Cpart」の「controlName」はそれぞれ「AisacControl_00」「AisacControl_01」「AisacControl_02」とします(AtomCraftで設定したAISACコントロールの名前を入れます)
「ADXController.cs」の処理としては、「aisicValue」を常に監視しておりその値を「IMLoop(CriAtomSource)」のAISACコントロールに渡すというものです。(初期値は0に設定)
また「OnTrigger〇〇」では自身の「BoxCollider」にプレイヤーが侵入した場合にAnimatorにそのことを知らせます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AdxControll : MonoBehaviour
{
public CriAtomSource bgmCriAtomSource;
private Animator animator;
public string controlName;
public float aisicValue;
void Start()
{
bgmCriAtomSource.SetAisacControl(controlName, 0);
animator = GetComponent<Animator>();
}
void Update()
{
bgmCriAtomSource.SetAisacControl(controlName, aisicValue);
}
public void SetValueToBGMAISAC(float aisacValue)
{
bgmCriAtomSource.SetAisacControl("BgmMixControl", aisacValue);
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player") animator.SetTrigger("FadeIn");
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == "Player") animator.SetTrigger("FadeOut");
}
}
AISAC値の制御
今回の例ではUnity標準のAnimation、Animatorの機能を利用し、以下のオブジェクトの作成と設定をします。
- 「IMLoop」という名前の「Animator Controller」を作成
- 「FadeIn」「FadeOut」という名前の「Animation」を作成しLoopTimeのチェックを外す
- 前項で作成した全ての「Trigger_○part」オブジェクトの「Animator」の「Controller」に「IMLoop」を設定
Animatorの設定
IMLoopをダブルクリックし以下の画像のように設定します。
Animatorでは外部の入力値によってどのようなAnimationを実行するかを設定します。Box Colliderにプレイヤーが侵入(退出)した場合に「FadeIn」「FadeOut」という入力を受け取り、Animationで設定するフェード処理が実行されるようにします。
- +をクリックし「FadeOut」「FadeIn」という名前のTriggerを作成
- ステートを追加し「Initial」「FadeOutState」「FadeInState」という名前に設定
- 「FadeOutState」「FadeInState」の「Motion」をそれぞれ「FadeOut」「FadeIn」に設定
- MakeTransitionで各ステートを繋ぎ「Condition」を設定する
- 「FadeInState」へ向かうTransitionでは「FadeIn」を設定
- 「FadeOutState」へ向かうTransitionでは「FadeOut」を設定
Animationの設定
「FadeIn」「FadeOut」をダブルクリックし以下の画像のように設定します。
AnimationはAnimatorから呼び出して使用します。呼び出された場合、設定するアニメーションカーブに従って「ADXController.cs」の「aisicValue」を変化させます。「ADXController.cs」が「aisicValue」を「AISACコントロール」に適用することにより、各トラックがフェードすることになります。
- 「Trigger_○part」を選択した状態でAnimationタブを開く
- 「AddProperty」>「AdxControll」>「AisacValue」を追加
- 「Curves」タブでAISACに値与えるためのカーブを設定
- 「FadeIn」では0:00は0、1:00は1に設定
- 「FadeOut」では0:00は1、1:00は0に設定
テスト実行
ここまで出来たら実行し、プレイヤーをSceneビューで動かして「Trigger_○part」それぞれのコライダーの中に移動させてみます。
想定通り、Aパート、Bパート、Cパートと次々にフェードイン(アウト)するかどうか確認します。
その他
AdxControll.csについて
サンプルでは標準の機能で簡単に実装するため、UpdateでAisacValueを監視してSetAisacControlを実行、その値はAnimationで変更という方法をとっています。この場合、AisacValueに変化がない場合もUpdate処理が走り無駄な負荷が増えるため、Updateは使わず、Tweenライブラリで変化させたりUniRxのReactivePropertyを利用したりするほうが良いかもしれません。