はじめに
今日のカタログIPゲームジャム事前勉強会にて
どうやら素材はイントロ(開始ジングル)とループ部分で分かれているwav素材っぽいので、
誰でも簡単にイントロ付きループBGMを再生するためだけのスクリプトを書いてみた。
サンプルプロジェクト:
https://github.com/tatmos/BGM_Intro_loop
ニコニコ動画【SKY KID】【Unity】簡単にイントロ付きループBGMを再生するスクリプト
http://www.nicovideo.jp/watch/sm27490070
スカイキッドが例に挙げられていたけど、この曲、
ループ部分が前のめり(前に飛び出している、アウフタクト)なのです。
アウフタクトとは?
イントロ2小節で、普通は、4拍+4拍で8拍で
1,2,3,4,5,6,7,8とカウントすると、
8のところからループ部分のメロディーが始まるのです。
(アバウトには2小節だけど厳密には少し短い)
この図だと3小節目の4拍目から7小節目の3拍までをループとして録音しています。
(曲構成と実ループ範囲がずれるのはよくある。ゲーム向けにループ区間を録音する時は少々パズルで、最適なデータのためにDAW上の構成をいじったりといった見えない作業が発生します。実際の録音範囲はループ(2回目)を使っています)
スクリプトについて
PlayScheduledを使っています。
あらかじめ鳴らすタイミングがわかっていたらこれで鳴らせます。(キャンセルできるか不明ですが・・・)
using UnityEngine;
using System.Collections;
public class BGMController : MonoBehaviour {
public AudioClip intro;
public AudioClip loop;
AudioSource[] audioSource = new AudioSource[2];
// Use this for initialization
void Start () {
audioSource[0] = this.gameObject.AddComponent();
audioSource[1] = this.gameObject.AddComponent();
if(intro != null){
audioSource[0].playOnAwake = false;
audioSource[0].clip = intro;
audioSource[0].Play();
if(loop != null){
audioSource[1].playOnAwake = false;
audioSource[1].clip = loop;
audioSource[1].loop = true;
audioSource[1].PlayScheduled(AudioSettings.dspTime + intro.length);
}
}
}
// Update is called once per frame
void Update () {
}
}
AudioSettings.dspTimeってのが、どうやらオーディオ初期化してからずっとカウントしているタイマーっぽい。
これをマスターのタイマーとして再生タイミングを合わせるのがPlayScheduledという処理の様子。
##追記
上のスクリプトはたまに繋ぎがうまくいかないことがあるので
【Unity】誰でも簡単にイントロ付きループBGMを再生するスクリプト2015-11-01繋ぎ改善版
をあげました。スクリプトだけ使いたいひとは上のリンク先のを使ってください。
ADX2でループ再生も検討
まぁ、ADX2とかでループ組んで再生する方がスクリプトレスでキュー再生だけで書けるので扱う音数が多くてインポートの時間節約したいとかであれば、ADX2おすすめしておきます。
でも、最近はループが組める波形編集ソフトがめっきり無くなってしまったので、
- シーケンスとかで並べてみたり
ありかと思われます。
##余談
-
PlayScheduledのこぼればなし
ちなみに、PlayScheduledが無かった時は何かダミー再生していたオーディオ処理サンプル数とかから計算してプリディレイ再生とかしてた時もありました。 -
もしかして7/4拍子のイントロという可能性も微レ存
アレンジとしてまれによくある。8拍くると思わせておいて、8->7拍子を挟むことで、裏を表としてカウントした時とか少し楽くなる。ちょっと勢いをつけたい時とかいごく少量使うのがポイント。