UnityAudioのスクリプトの中に、PlayClipAtPointというコマンドがあります。指定した座標でオーディオクリップを再生するためのもので、3Dゲームを作る際に簡単に音を再生できる便利なコマンドです。
ところがこのコマンドはAudioMixerへの出力先指定ができません。例えば洞窟のような場所に入った際に反響音のエフェクトをかけたいといったような時、これではちょっと不便です。
調べてみたのですが、他にAudioMixerへの出力指定ができそうなコマンドもないようなので、自分で似たようなコマンドを作ることにしました。
処理の概要
といってもやっていることは単純です。UnityのPlayClipAtPointのスクリプトリファレンスによると、「この関数は AudioSource を作成しますがクリップの再生が終了したらそれを自動的に破棄します。」と書かれていますので、同じように、一時的に空オブジェクトを作成して音声を再生させます。
処理の流れ
- 空のオブジェクトを作成してAudioSourceをアタッチ。
- オブジェクトを再生座標に移動させる
- オーディオクリップを再生
- 再生時間を超えたらオブジェクトを破棄する。
スクリプト
作成したスクリプトは以下になります。
private void PlayAt3D(AudioClip audio,GameObject Model,float ClipVolume)
{
// 「GameObject名 & "-Audio"」 という名前のゲームオブジェクトを作成
GameObject Model_tmp = new GameObject(Model.name + "-Audio");
//GameObjectにAudioSourceをアタッチ
AudioSource audio_tmp = new AudioSource();
audio_tmp = Model_tmp.AddComponent<AudioSource>();
//オーディオソースの設定
audio_tmp.clip = audio;
audio_tmp.transform.position = Model.transform.position;
audio_tmp.spatialBlend = 1;//3D音響にするプロパティ(1だと3D、0だと2D)
audio_tmp.loop = false;//ループオフ
audio_tmp.volume = ClipVolume;
audio_tmp.outputAudioMixerGroup = (指定したいオーディオミキサーのアウトプット);
//再生
audio_tmp.Play();
//クリップ長+0.1秒でオブジェクトを破棄
Destroy(Model_tmp, audio.length + 0.1f);}
}
補足
- 私の環境では、スクリプト内で呼び出しているためPrivate関数になっています。用途に応じてPublic関数にしても良いかもしれません。
- また、オブジェクトをインスペクタ画面からドラッグ&ドロップして指定したかったのと、一時生成されるオブジェクトにGameObjectの名前をつけてデバッグしやすくしたかったという理由があったため、引数をGameObjectにして、transform.positionから座標を取得しています。ここも用途に応じてVector3を引数にするように書き換えてしまっても良いと思います。
- オブジェクトの破棄の際、audio.Clipの長さぴったりで破棄してしまうことに抵抗があったため、なんとなく+0.1秒追加していますが、ぴったりでも問題ないかもしれません。
- そのほか、outputAudioMixerGroupを引数に出したり、spartialBrendを指定できるようにしたりと、環境に合わせてカスタマイズすると良いかと思います。