結月ゆかり、弦巻マキ、ゆっくり霊夢のゲームを作る過程で、オーディオ・スペクトラムの取得方法など調べているうちに、一度オーディオ・ヴィジュアライザーを作ったほうが理解しやすいのでUnity5で作成しました。
画像の青いスペクトラムのソースコードが以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using UnityEngine; using System.Collections; public class Spectrum2 : MonoBehaviour { public GameObject cube2; public int numberOfObjects = 2 * 2 * 2 * 2 * 2 * 2; float[] samples = new float[2048]; public GameObject[] lines; void Start () { lines = new GameObject[2048]; for (int i = 0; i < 2048; i++) { Vector3 pos = new Vector3 (0.1f * i - 15f, 0f, 10f); var obj = Instantiate (cube2, pos, Quaternion.identity) as GameObject; lines [i] = obj; } } void Update () { AudioListener.GetSpectrumData (samples, 0, FFTWindow.BlackmanHarris); // show lines for (int i = 0; i < 2048; i++) { Vector3 s = lines [i].transform.localScale; //s.y = Mathf.Lerp (s.y, samples [i] * 200, Time.deltaTime * 30); s.y = samples [i] * 200; lines [i].transform.localScale = s; } } } |
まず、プリミティブのキューブを2048個並べます。手動で並べるのは面倒なので、for文とInstantiateで生成します。キューブは、CreatePrimitiveで作成しても構いません。キューブは当然Transformコンポーネントを持っているので、localScaleプロパティーで、サイズを変更できます。
CreatePrimiviteでキューブを作成する場合は、GameObject.CreatePrimitiveです。
1 |
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); |
スペクトラムを取得するには、GetSpectrumDataを使います。Unity5.3場合は、第一引数にあらかじめ、領域確保した配列を渡して呼び出せば、結果としてそこにデータが返ってきます。以前のAPIでは戻り値でデータを取得しましたが今は非推奨です。このサンプルでは、配列のサイズは2048にしていますが、2のN乗の値であれば問題ないようです。
あとは、gameobject.transform.localScaleのY軸にこのスペクトラムデータと倍率を渡して、キューブのY座標が大きく増減するようにしています。これでオーディオヴィジュアライザーの完成です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
float[] samples = new float[2048]; void Update () { AudioListener.GetSpectrumData (samples, 0, FFTWindow.BlackmanHarris); // show lines for (int i = 0; i < 2048; i++) { Vector3 s = lines [i].transform.localScale; s.y = samples [i] * 200; lines [i].transform.localScale = s; } } |
キューブを円状に並べる場合は、Mathf.Cos、Mathf.Sinで単位円(半径1の円)のXY座標が求められるので、radiusで大きくしてあげればよいです。これはUnityに限らず三角関数のお約束みたいなコードです。
1 2 3 4 5 6 7 8 9 |
void Update () { for (int i = 0; i < 12; i++) { float angle = i * Mathf.PI * 2 / 12; Vector3 pos = new Vector3 (Mathf.Cos (angle), 0, Mathf.Sin (angle)) * radius; Instantiate (prefab, pos, Quaternion.identity); } } |
このプロジェクトの配布
http://hajimete-program.com/games/VisualGround2.zip
音声ファイルは、二次配布になるため削除しています。http://www.d-elf.com/ さんに良い曲がいっぱいあります。