[Unity] BGM や効果音を いい感じに鳴らすライブラリを作る [ゲーム開発ログ 2020-12-19]

2020-12-19

俺による俺のためのイイ感じの AudioPlayer

Unity にはゲーム開発に必要な道具が大体揃っている。オーディオ再生もそのひとつだ。 が、道具を取り出しやすいところに置いたり、自分に使いやすい状態に並べたりするのは個々のプログラマの仕事だ。

実際、ちょっとしたモックを作るときは Unity の用意した API を呼ぶだけで事足りるが、 細かい制御をしたくなったりすると、自分でちょっとライブラリレイヤーを仕立てる必要が出てくる。

例えば

  • 音量のフェードイン・フェードアウトを楽に書きたい
  • シーン遷移中にも音を鳴らし続けたい
    • (※ Main Camera に Audio Listener をつける作りだと、遷移処理中のカメラが無い期間に音が途切れる)
  • ピッチを変えつつ 3D サウンドを鳴らしたい

といったことをやりたくなった場合、Unity 標準の API を単に呼ぶだけでは実現できない。

ということで、自前の AudioPlayer ライブラリを実装した。

自分の実装

ゲームプログラマであれば、こういう AudioPlayer 的なコードを実装したことのある人は多いと思うが、 細かい内部仕様やインタフェース設計なんかは人によって差が出るものだ。

自分の実装はこんな感じになった:

(※ 自前のフレームワークに依存したコードで、フレームワークごと持ってこないと動かないので注意)

こんな感じで書けるようになっている:

// 普通に再生。アセットアドレスを渡す方法と AudioClip を直接渡す方法がある
Alto.bgm.Play(AssetAddress.BGM_Stage_1);
Alto.bgm.Play(audioClip);

// BGM と効果音は Alto.bgm と Alto.se で再生プールやデフォルト設定を分けている。機能は同じ
Alto.bgm.Play(AssetAddress.BGM_Stage_1);
Alto.se.Play(AssetAddress.SE_Click);

// 引数でピッチとか、すでに鳴っていても再生し直すかなど色々指定できる
Alto.bgm.Play(AssetAddress.BGM_Stage_1, pitch: 0.89089f, replay: true);

// 止める。音源を指定すると指定した音源だけを止める
Alto.bgm.Stop();
Alto.bgm.Stop(AssetAddress.BGM_Stage_1);

// 中断と再開。これも音源指定が可能
Alto.bgm.Pause();
Alto.bgm.Resume();

// フェードイン / フェードアウト / クロスフェード
Alto.bgm.FadeIn(AssetAddress.BGM_Title, 4.0f);
Alto.bgm.FadeOut(4.0f);
Alto.bgm.CrossFade(AssetAddress.BGM_Stage_1, 4.0f, 0f, 4.0f)

// ジングルを鳴らす時など、一定時間 BGM の音量を絞る
Alto.bgm.Ducking(audioClip.length);

// マスターボリューム設定はシステムとユーザの 2 つをかけ合わせる
Alto.bgm.systemMasterVolume = 0.8f;
Alto.bgm.userMasterVolume = 0.8f;

こだわりポイント

  • 基本的にデフォルト引数で動いて、カスタムしたいところだけ指定すれば良い形にした
  • 3D サウンドに対応(再生の座標を指定できる)
  • 同じ音が同時に鳴ったときに音量が爆発しないように自動調整(OFF にもできる)
  • ボイスやジングルを鳴らす時用に、一定時間音量を絞る機能(Ducking とか言うらしい)
  • 音量のフェードを単純な線形ではなく、音が小さい時に徐々に絞るようなカーブで制御
    • (人間の耳にはその方が自然なフェードに聞こえるため)

自前実装するのは手間がかかるが、こういう細かいところにこだわれる楽しみもある。

開発時のサウンドテスト画面

大体これでやりたいことはできるようになった。
お気に入りのオーディオ再生ライブラリが実装できたので、どんどん音を鳴らしていこう。


付録 : 音階に対応した Unity の pitch 値

Unity の AudioSource の pitch の値は、「0.5 を入れたら半分の速度になり、2.0 を入れたら倍の速度になる」 といった値になっている。音の周波数の特性的に、0.5 で 1 オクターブ下がり、2.0 で 1 オクターブ上がることになる。

ではちょうど 1 音階ぶん(半音ぶん)下げたい、とかいった場合にはどういう値を入れたらよいのか? というのが計算しないとわからない感じだったので、計算してみた。

音階に対応した pitch の値

音階に対応した pitch の値

2 度下げたいと言った場合は 0.89089… を入れればよい。 BGM をちょっとピッチ変えて雰囲気変えたい場合などに、 きっちり音階の単位で変わらないと気持ち悪いという人向け。