ノーツをまとめて動かすためのオブジェクトを作る #
リズムゲームを動かす際には、前回の記事で作ったノーツをいくつも用意して動かすことになります。今回は、NotesParentという名前で空のオブジェクトを作ってその上にノーツを置き、NotesParentを動かすことですべてのノーツを動かしていこうと思います。
それでは、NotesParentを作っていきます。
- Hierarchyウィンドウの「+」マークをクリックします。
Create Emptyで空のオブジェクトを作ります。オブジェクト名はNotesParentにします。

作られたNotesParentの座標は初期状態のままにしておきます。
| X | Y | Z | |
|---|---|---|---|
| Position | 0 | 0 | 0 |
| Rotation | 0 | 0 | 0 |
| Scale | 1 | 1 | 1 |
前回の記事で作ったNoteを、NotesParentの子にします。
NoteをNotesParentにドラッグ&ドロップすると子にすることができます。

NoteをNotesParentの子にできていると、NotesParentの左側に▶のマークが出てきます。これをクリックすると、NotesParentの子であるNoteが見えます。

スクリプトを作成 #
これからノーツを動かすためのスクリプトを書いていきますが、その前にまずはスクリプトを保存しておくフォルダを作ります。Projectウィンドウから、Assetsフォルダ内で新しいフォルダを作ります。
- Projectウィンドウで
Assetsフォルダ内に移動し、空いているところで右クリックします。 Create>Folderで新しいフォルダを作成します。フォルダ名はScriptsとします。

フォルダが作れたので、スクリプトを作成します。
Scriptsフォルダ内に移動します。- 空いているところで右クリックします。
Create>MonoBehaviour Scriptを選択してスクリプトを作成します。スクリプト名はNotesMoverにします。


スクリプトを新規作成したときに名前を変えそびれた場合や、後からスクリプト名を変更する場合は、中身のクラス名も変えるようにしましょう。
クラス名は、public class ○○ : MonoBehaviourの○○の部分です。
一定速度でノーツを動かす #
スクリプトが作成できたら、ダブルクリックして開いてみましょう。
コードエディタでスクリプトが開かれ、以下のようになっていると思います。
1using UnityEngine;
2
3public class NotesMover : MonoBehaviour
4{
5 // Start is called once before the first execution of Update after the MonoBehaviour is created
6 void Start()
7 {
8
9 }
10
11 // Update is called once per frame
12 void Update()
13 {
14
15 }
16}コメントは消しておきます。
1using UnityEngine;
2
3public class NotesMover : MonoBehaviour
4{
5 void Start()
6 {
7
8 }
9
10 void Update()
11 {
12
13 }
14}さて、どんな処理をすればノーツを動かせるでしょうか?
ノーツを動かすには、ゲームが始まってからの経過時間を計算し、その時間に応じてノーツの位置を変えていく必要があります。そのため、2つの処理を用意します。
-
ゲーム開始時刻を記録する
Startメソッドで現在時刻を変数に保存しておきます。 -
毎フレーム、経過時間を計算して座標を更新する
Updateメソッドで「現在時刻 - 開始時刻」を計算し、その値をNotesParentのZ座標に設定します。
UnityではTime.timeでゲーム開始からの経過時間が取得でき、transform.positionでオブジェクトの座標を変更できます。
それでは、実際にコードを書いてみましょう。
1using UnityEngine;
2
3public class NotesMover : MonoBehaviour
4{
5 float startTime;
6
7 void Start()
8 {
9 startTime = Time.time;
10 }
11
12 void Update()
13 {
14 float elapsedTime = Time.time - startTime;
15 transform.position = new(0.0f, 0.0f, elapsedTime);
16 }
17}startTimeはゲーム開始時刻を記録する変数です。Startメソッド内でゲーム開始時の時刻を記録しています。
Updateメソッド内では、現在時刻から開始時刻を引いて経過時間(elapsedTime)を計算し、NotesParentの座標を変更しています。
これでゲーム内時間に応じてノーツを動かすスクリプトが書けました。スクリプトを保存してUnityエディタに戻ります。
今書いたスクリプトをNotesParentにアタッチして実際に動かしてみましょう。
ProjectウィンドウのAssets > Scripts にあるNotesMoverを、HierarchyウィンドウのNotesParentにドラッグ&ドロップします。


これで書いたスクリプトをNotesParentにアタッチできましたので、Unity中央上の再生ボタンをクリックして実行します。
逆方向ですが、ノーツが動きました!
Unityエディタから動く速度を変えられるようにする #
ノーツは動きましたが、ノーツが動く方向と速度を調整したいですね。
ノーツの位置を決めている部分は、NotesMoverのUpdateメソッド内、new(0.0f, 0.0f, elapsedTime)の部分です。これを、new(0.0f, 0.0f, -5.0f * elapsedTime)のようにすれば逆方向に速く動きそうです。
このようにしても良いのですが、ノーツの速度は頻繁に変えたくなるかもしれないので、数値をUnityエディタから変えられるようにしてみたいと思います。
変数を宣言するときに[SerializeField]という言葉を加えるとUnityのエディタ上で数値を調整できるようになります。

ノーツのスピードを示す変数noteSpeedを用意して、Unityエディタ側から編集できるようにします。
1using UnityEngine;
2
3public class NotesMover : MonoBehaviour
4{
5 [SerializeField] float noteSpeed;
6 float startTime;
7
8 // ...(以下省略)
9}ノーツの速度を管理する変数を用意できたので、次はnoteSpeedの値に応じて移動速度が変わるようにします。
NotesMoverのUpdateメソッド、ノーツの位置を変えている部分を変更します。
1using UnityEngine;
2
3public class NotesMover : MonoBehaviour
4{
5 [SerializeField] float noteSpeed;
6 float startTime;
7
8 void Start()
9 {
10 startTime = Time.time;
11 }
12
13 void Update()
14 {
15 float elapsedTime = Time.time - startTime;
16 transform.position = new(0.0f, 0.0f, -noteSpeed * elapsedTime);
17 }
18}保存してUnityエディタに戻ります。
Unityエディタ側から設定できるようにしたnoteSpeedを設定します。
- Hierarchyウィンドウから
NotesParentを選択します。 - Inspectorウィンドウを見ると
Note Speedという項目が追加されているので、5に設定します。

これで再生ボタンをクリックしてみると、ノーツが画面下向きに速く動きます!(Gameビューだとすぐに画面下に行ってしまいますが、Sceneビューから見るとちゃんと動いていることがわかります)
HierarchyウィンドウのNotesParent > NoteのPositionのZを10にするとGameビューでもノーツが動いていることが確認できます。
確認が終わったら、HierarchyウィンドウのNoteは消しておきましょう。
まとめと次回予告 #
今回は、ノーツを動かすスクリプトを作り、ノーツを動かしました。ゲーム開始からの経過時間をもとにNotesParentの座標を変えることでノーツを動かし、noteSpeedを使ってノーツの速度をUnityエディタから変えられるようにしました。
次回はプログラミングから少し離れ、リズムゲームの譜面を作っていきます。
今回は以上になります。お疲れ様でした!