今回はAudioの扱い方です。 3Dサウンドについては触れず、社内で扱う事の多い2Dサウンドを前提にして書いていきます。
こんにちは、ソーシャルゲーム事業部所属エンジニアのぴーちんです!!宜しくお願いしますヾ(@⌒ー⌒@)ノ
この記事はカヤックUnityアドベントカレンダー2016の17日目の記事になります。
Audioの扱いについて
Unityで音を鳴らす仕組みの基本
Unityの音は AudioClip, AudioSource, AudioListener, AudioMixer などのComponentによって鳴らされています。
AudioClipをAudioSourceが再生し、AudioListnerがそれを受信して、物理的なスピーカーなどを通じて私達へ音を届けてくれます。 この関係は公式マニュアルのAudioOverViewで詳しく説明されています。
また、AudioListnerが音を受信する前にAudioMixerを介する事で、音にエフェクトをかけたり音量を調整したりする事が可能です。 この関係は公式マニュアルのAudioMixerOverviewで詳しく説明されています。
AudioMixerの他にも、AudioSourceやAudioListnerが付いてるGameObjectに AudioFIlter 関連のComponentを付けて音を調整する方法もあります。
Unityで扱える音声フォーマットの種類について
Unityでは以下のフォーマットがサポートされています。
理由は後述しますが、 社内では基本的に .wav
などの非圧縮フォーマットを扱う場合が多いです。
https://docs.unity3d.com/ja/current/Manual/AudioFiles.html
AudioFileとAudioFormatの関係
UnityにimpotしたAudioFile( .mp3
, .wav
など)は、そのままゲームに使われるわけではありません。
UnityへimportしたAudioFileは AudioClip
としてUnityに取り込まれ、ゲーム内で扱われるサウンドはAudioClipのInspectorで設定されたものが再生される事になります。
なので、元のオーディオファイルがそのまま再生されるわけでなく、インポート時に指定形式に変換されたサウンドがUnity内で扱われる事になります。
この仕組みについては10日目の『Texture File と Texture Formatの関係』でも触れられていますので、詳細は割愛します。
音声ファイルの品質について
.ogg
や .mp3
などの非可逆圧縮されるフォーマットをUnityへimportする際の注意点があります。
現時点でUnityはデフォルトで非可逆圧縮フォーマットの Vorbis 形式(.ogg)
に設定されてしまいます。
非可逆圧縮形式の音声を再圧縮してしまう場合、再生時の劣化が多くなってしまいます。
どうやらデフォルトの圧縮設定はUnity5から変更された様です。 詳しくは公式マニュアルを参照してください。
一方で .wav
や aiff
などの無圧縮フォーマットをUnityへimportする際には、上記の様な心配事はありません。
AudioClipのInspectorの設定次第で、生データのまま扱う事も非可逆圧縮形式に設定する事も可能です。
基本的に社内のモバイルゲーム開発ではBGM/SE両方で .wav
を使用する場合が多いです。
理由としては、Unityへimport後に圧縮設定が行えるので、わざわざ圧縮されたファイルをUnityへimportする必要が無いからです。
AssetPostprocessor
先程はAudioClipのInspectorから、圧縮の設定や読み込み方法を設定可能な事について触れました。 基本的にチームで開発する際にAudioClipの設定は、設定漏れやミスをを避ける為に自動で処理します。 UnityにはAssetの変更時などイベントをHookする機能が提供されています。
AudioのimportをHookするには OnPostprocessAudioを使います。
設定例
using UnityEditor; using UnityEngine; public class AssetPostprocessAudio : AssetPostprocessor { private void OnPreprocessAudio() { var importer = assetImporter as AudioImporter; importer.forceToMono = false; importer.loadInBackground = false; importer.preloadAudioData = true; var settings = new AudioImporterSampleSettings() { compressionFormat = AudioCompressionFormat.MP3, // mp3に圧縮します loadType = AudioClipLoadType.CompressedInMemory, // 圧縮された状態でメモリに保持されます quality = 0.15f, // 品質の設定 sampleRateOverride = 44100, // AudioClipのsamplingRateを44,1kHzに設定 ※1 }; importer.SetOverrideSampleSettings("iOS", settings); importer.SetOverrideSampleSettings("Android", settings); } }
AudioClipのsamplingRateを44,1kHzに設定 ※1
AudioManagerから音出力時のSamplingRateを指定出来るので、もしUnityへimportした音データのSamplingRateがそこで設定された値以上の場合には無駄になるので、import時に調整してあげましょう。
AudioManagerから音出力時のSamplingRateを指定出来る
先ほど紹介したのはAudioClipのSamplingRateについてですが、音を出力する際のSamplingRateをグローバルに設定する事が可能です。 それらを以下で紹介します。
AudioManager
UnityEditorのEdit->ProjectSettings->Audioから開ける設定画面です。
ここでのSamplingRateの設定が0の場合に、iOS/Androidだとデフォルトで出力時のSamplingRateが24kHzになってしまいます。 困る場合にはゲームに適したSamplingRateを設定しておきましょう。 社内ではプロジェクトによりますが、44,1kHzに設定しておく事が多いです。
このTipsはUnityの公式ブログにて紹介されています。
その他の詳しい情報は公式マニュアルをご覧ください
AudioSettings
Unity5から AudioSettingsというランタイムのみに適用される、グローバルな設定を管理可能なAPIが提供されています。
使うケースですが、ゲームの設定画面にて AudioConfiguration の設定項目をユーザーに設定させて、その場で設定を反映する。
具体的なコードを交えた使用例はAudioSettings.ResetのScriptReferenceに例が記載されてるので、割愛します。
SEとBGMの音の鳴らし方の違い
ゲームでは基本的にSE/BGMの2種類の音を扱います。 この2種類の音を再生する場合の違いを紹介します。
BGM
BGMは基本的に『途切れずに鳴らせる』設計にするべきです。 なので、BGMを鳴らす専用のAudioSourceを最低でも2つ用意します。 理由としては、ゲームの特性によりますが、多くのゲームでBGMをクロスフェードさせる場合が多いです。
コード例としては、以下の様な感じになります。 最近はDOTweenだけで簡単なCrossFade処理なら書ける様です、便利ですね。
ちなみに DOTweenについては『【Unity】Tween アニメーション(DOTween)の話』で紹介されていますので、合わせてお読み下さい。
using UnityEngine; using DG.Tweening; public class BGMCrossFadeSample : MonoBehaviour { // BGM再生用のAudioSourceを2つ用意 [SerializeField] private AudioSource _source0; [SerializeField] private AudioSource _source1; public void CrossFade(float maxVolume, float fadingTime) { var fadeInSource = _source0.isPlaying ? _source1 : _source0; var fadeOutSource = _source0.isPlaying ? _source0 : _source1; fadeInSource.Play(); fadeInSource.DOKill(); fadeInSource.DOFade(maxVolume, fadingTime); fadeOutSource.DOKill(); fadeOutSource.DOFade(0, fadingTime); } }
SE
SEはBGMと違い、継続して鳴らさなくて良いです。 しかしSEは『同時再生可能』な様に設計しなければいけません。 それはゲームの特性によって変わるので固定でAudioSourceを用意するも良いですし、可変にAudioSourceのinstanceを増やす仕組みを作るという選択肢もあります。
コード例は少し大変だったので割愛します。インターネットで検索すると書いてる人が多いので参考にして下さい。
AudioMixer
Unity5から音をMixingする為のEditorが公式でサポートされました。 サウンドのミキシング、エフェクト、マスタリングなどの機能があります。
詳しくはUnityのマニュアルや動画のチュートリアルを見ると良いでしょう。
(ちなみにこの記事の時点では、まだ弊社では本格的に使った事例はありません)
調整した設定は .mixer
ファイルとして保存できるので、サウンドの調整をディレクターなどと分業する事がしやすくなります。
.mixer
ファイルにはゲーム内で扱うグローバルな設定をするのが良さそうです。
特別な設定が必要な時はScriptなどで済ますのが良さそうです。
使用例
- ストーリー画面でBGMとキャラボイスが混在する場合、ボイスの音が発生されたタイミングではBGMの音量を下げたい時(Ducking)
- 洞窟にキャラクターが歩いてる時に音が響く様にしたい時(Reverb)
おわりに
明日はローカルデータの保存についての記事になります。 担当はしみーさんになります。 お楽しみに。