Unityで音ゲーつくる ノーツを流す
現在こんな感じです!
単ノーツが流れるようになりました。
開始から2秒後に1つ目のノーツ、3秒後に2つ目のノーツ、5秒後に3つ目と4つ目のノーツが判定ゾーンに重なることが分かると思います。これは1秒間に1回分の拍(ノーツ同士の時間間隔)があるからで、1分間で数えると60回分の拍があることになります。これを60BPM(Beat per Minute)といいます。BPMは1分あたりの拍の数を表します。わかりやすい言葉でいうと「テンポ」です。
この拍と秒数をお互いに変換させれば何秒後に何拍目(ノーツ)が来るか(もしくはその逆)を計算できるようになります。BPMは1分間の拍の回数なのでそれを60で割ると1秒間の拍の回数が分かります。よって、秒数と拍は以下のような関係になることが分かると思います。
秒数:拍 = 1:(BPM ÷ 60)
比の性質から秒数から拍を求めたい時は秒数に(BPM ÷ 60)をかけ、拍から秒数を求めたい時は拍を(BPM ÷ 60)で割ります。コードで書くと以下のようになります。
public static float ToSec(float beat, float tempo) { // 60f : 一分間の秒数 return beat / (tempo / 60f); } public static float ToBeat(float sec, float tempo) { // 60f : 一分間の秒数 return sec * (tempo / 60f); }
リズムゲームの中には途中でBPMが変化するものもありますが今回は純粋にBPMを一定としたいと思います。
また、ノーツとその動きの流れについて考えてみます。
上の画像の例のように60BPMとします。"1秒後に1拍目"で"ノーツは来ない"で、"2秒後に2拍目"で"ノーツが来てます"ね。
まず予めに生成するノーツそれぞれに「何拍目のノーツか」あるいは「何秒目のノーツか」というプロパティを持たせる必要があります。どちらでもいいですが今回は「何拍目のノーツか」というプロパティを持たせることにしましょう。
public class NoteProperty { //何拍目のノーツか public float beat { get; } public int lane { get; } public NoteType noteType { get; } public NoteProperty(float beat, int lane, NoteType noteType) { //new NoteProperty(1, 0, NoteType.Single) のように宣言する this.beat = beat; this.lane = lane; this.noteType = noteType; } public enum NoteType { Single } }
こんな感じです。laneはレーンで2列あるうちのどちらかで、noteTypeはノーツの種類を格納しています。
void Update() { currentSec = Time.time; currentBeat = ToBeat(currentSec, 60f); position.y = (noteProperty.beat - currentBeat) * scrollSpeed; }
ノーツのy座標は「そのノーツが何拍目か」と「曲が始まってから現在何拍目か」の差で求めることにします。少し分かりづらいですが拍は秒数にも変換することができるので「そのノーツが何秒目か」と「曲が始まってから現在何秒か」の差で考えた方が分かりやすいと思います。お互いの差が0であるということはノーツと判定ゾーンのy座標が一致しているということです。判定機能を実装するにはこの一致しているかどうかというところを見極めればいいわけです。
大雑把な説明ですが自分用ですので悪しからず、続きも頑張ります。
Unityで音ゲーつくる 案
こんなイメージで作りたいと思います。(こういうのを考えてる時って楽しいよね)
Unityの勉強も兼ねていますがそもそもリズムゲームに対する知識が薄弱なので(経験はそこそこありますが)そこから勉強する必要がありそうです。
サイトや技術書を参考にしながら2週間で完成することを目標にしたいと思います。