またUnityの記事です。今回は難易度低め。
BGMを流すとき、イントロ+ループというのを前提にしたBGMって結構あると思います。
Unityではそれを再生する機能が標準でない(Why?)ので、簡単に出来るのを実装してみました。
必要なものは
・イントロとループで分けたAudioClip
だけです。わざわざ分けるのめんどいですが実装が簡単な分こっちに手間がかかるということで...
ソースは以下です。改良なり再配布なりご自由にどうぞ。
(再生、停止の最低限の機能しかないです)
public class BGMPlayer : MonoBehaviour { [SerializeField] AudioClip bgmIntroAudioClip; [SerializeField] AudioClip bgmLoopAudioClip; AudioSource introAudioSource; AudioSource loopAudioSource; void Start() { introAudioSource = gameObject.AddComponent <AudioSource>(); loopAudioSource = gameObject.AddComponent <AudioSource>(); introAudioSource.clip = bgmIntroAudioClip; introAudioSource.loop = false; introAudioSource.playOnAwake = false; loopAudioSource.clip = bgmLoopAudioClip; loopAudioSource.loop = true; loopAudioSource.playOnAwake = false; } public void PlayBGM() { if (introAudioSource == null || loopAudioSource == null) { return; } introAudioSource.Play (); loopAudioSource.PlayScheduled (AudioSettings.dspTime + bgmIntroAudioClip.length); } public void StopBGM() { if (introAudioSource == null || loopAudioSource == null) { return; } if (introAudioSource.isPlaying) { introAudioSource.Stop (); } else if (loopAudioSource.isPlaying) { loopAudioSource.Stop (); } } }
解説
インスペクタにイントロとループのAudioClipをそれぞれ設定すれば再生出来ます。
今回のやりかたは、AudioSourceをイントロとループでそれぞれ用意して、イントロの再生が終わった瞬間からループを再生する。
という仕組みになっています。
PlayScheduled()を使うことで、再生を遅延させることができます。AudioSetttings.dspTimeはTime.timeとは別に、オーディオを再生するための正しい時間みたいなものです。
時間指定で音を再生する場合はこれ使ったほうがいいと思います。
別の方法
他の方法として、AudioSourceは1つで、イントロの再生が終わると同時にClipを入れ替えるという方法もありますが、切り替えの瞬間にどうしてもノイズが走ってしまいます。
フレーム単位でしか切り替えられないので当然っちゃ当然なんですが、解決方法イマイチわからず...
一番はAudioSourceもAudioClipも1つだけで、ループを開始してほしい時間を指定すれば動いてくれるスクリプトなんですが、色々試した結果上記の方法が一番実装は楽そうでした。
多分サンプルレートとかも考慮して組まないと駄目な気がします。
蛇足
今回の調べて思ったんですが、Unityのマニュアルとリファレンスの音周りがほとんど翻訳されてないのが軽く衝撃でした。