こんにちは、マサです。
前回はスコアを表示させるところまでやりました。
今回は、minoが上まで積み上がるとゲームオーバーでリスタートするのと、
スコアが1500になるとゲームがクリアしてリスタートするという処理を追加します。
GameOverとGameClearメソッドを追加
まずは、コードをすべて載せます。
確認しつつ、どういう処理になっているのか?確認しましょう。
※今回追加したコードは”//今回の追加“と記載してます
GameManagementスクリプト
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | using System.Collections; using System.Collections.Generic; using UnityEngine; // 今回の追加 using UnityEngine.SceneManagement; using UnityEngine.UI; public class GameManagement : MonoBehaviour { // スコア関連 public Text scoreText; private int score; // 今回の追加 public int currentScore; public int clearScore = 1500; // Start is called before the first frame update void Start() { Initialize(); } // Update is called once per frame void Update() { } // ゲーム開始前の状態に戻す private void Initialize() { // スコアを0に戻す score = 0; } // スコアの追加 public void AddScore() { // 今回の追加 score += 100; currentScore += score; // 今回の追加 scoreからcurrentScoreに変更 scoreText.text = "Score: " + currentScore.ToString(); Debug.Log(currentScore); if (currentScore >= clearScore) { GameClear(); //Debug.Log(clearScore); } } // GameOverしたときの処理 // 今回の追加 public void GameOver() { SceneManager.LoadScene(SceneManager.GetActiveScene().name); } // GameClearした時の処理 // 今回の追加 public void GameClear() { SceneManager.LoadScene(SceneManager.GetActiveScene().name); } } |
Minoスクリプト
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class Mino : MonoBehaviour { public float previousTime; // minoの落ちる時間 public float fallTime = 1f; // ステージの大きさ private static int width = 10; private static int height = 20; // mino回転 public Vector3 rotationPoint; // grid private static Transform[,] grid = new Transform[width, height]; void Update() { MinoMovememt(); } private void MinoMovememt() { // 左矢印キーで左に動く if (Input.GetKeyDown(KeyCode.LeftArrow)) { transform.position += new Vector3(-1, 0, 0); if (!ValidMovement()) { transform.position -= new Vector3(-1, 0, 0); } } // 右矢印キーで右に動く else if (Input.GetKeyDown(KeyCode.RightArrow)) { transform.position += new Vector3(1, 0, 0); if (!ValidMovement()) { transform.position -= new Vector3(1, 0, 0); } } // 自動で下に移動させつつ、下矢印キーでも移動する else if (Input.GetKeyDown(KeyCode.DownArrow) || Time.time - previousTime >= fallTime) { transform.position += new Vector3(0, -1, 0); if (!ValidMovement()) { transform.position -= new Vector3(0, -1, 0); AddToGrid(); CheckLines(); this.enabled = false; FindObjectOfType<SpawnMino>().NewMino(); } previousTime = Time.time; } else if (Input.GetKeyDown(KeyCode.UpArrow)) { // ブロックの回転 transform.RotateAround(transform.TransformPoint(rotationPoint), new Vector3(0, 0, 1), 90); } } public void CheckLines() { for (int i = height - 1; i >= 0; i--) { if (HasLine(i)) { DeleteLine(i); RowDown(i); //Debug.Log(i); } } } // 列がそろっているか確認 bool HasLine(int i) { for (int j = 0; j < width; j++) { if (grid[j, i] == null) return false; //Debug.Log(j); } // 今回の追加 FindObjectOfType<GameManagement>().AddScore(); return true; } // ラインを消す void DeleteLine(int i) { for (int j = 0; j < width; j++) { Destroy(grid[j, i].gameObject); grid[j, i] = null; } } // 列を下げる public void RowDown(int i) { for (int y = i; y < height; y++) { for (int j = 0; j < width; j++) { if (grid[j, y] != null) { grid[j, y - 1] = grid[j, y]; grid[j, y] = null; grid[j, y - 1].transform.position -= new Vector3(0, 1, 0); } } } } void AddToGrid() { foreach (Transform children in transform) { int roundX = Mathf.RoundToInt(children.transform.position.x); int roundY = Mathf.RoundToInt(children.transform.position.y); grid[roundX, roundY] = children; // 今回の追加 // height-1 = 19のところまでブロックがきたらGameOver if (roundY >= height - 1) { // GameOverメソッドを呼び出す FindObjectOfType<GameManagement>().GameOver(); } } } // minoの移動範囲の制御 bool ValidMovement() { foreach (Transform children in transform) { int roundX = Mathf.RoundToInt(children.transform.position.x); int roundY = Mathf.RoundToInt(children.transform.position.y); // minoがステージよりはみ出さないように制御 if (roundX < 0 || roundX >= width || roundY < 0 || roundY >= height) { return false; } if (grid[roundX, roundY] != null) { return false; } } return true; } } |
それでは今回追加したコードを抜粋して解説します。
using UnityEngine.SceneManagement;の追加
1 2 | // 今回の追加 using UnityEngine.SceneManagement; |
Sceneの移動や切り替えやリロードの時に必要になります。
使い方は色々あるので、Unityのリファレンスを見るとより詳しく説明されています。
GameClearとGameOverメソッドを追加
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 37 38 39 40 41 42 43 44 | // スコア関連 public Text scoreText; private int score; // 今回の追加 public int currentScore; public int clearScore = 1500; // スコアの追加 public void AddScore() { // 今回の追加 score += 100; currentScore += score; // 今回の追加 scoreからcurrentScoreに変更 scoreText.text = "Score: " + currentScore.ToString(); Debug.Log(currentScore); if (currentScore >= clearScore) { GameClear(); //Debug.Log(clearScore); } } // GameOverしたときの処理 // 今回の追加 public void GameOver() { SceneManager.LoadScene(SceneManager.GetActiveScene().name); } // GameClearした時の処理 // 今回の追加 public void GameClear() { SceneManager.LoadScene(SceneManager.GetActiveScene().name); } |
まずは、下記のcurrentScoreとclearScoreを定義しました。
public int currentScore;
public int clearScore = 1500;
AddScoreメソッドでcurrentScoreがclearScoreを超えるとGameClearメソッドが呼び出されて、リロードするという処理にしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | void AddToGrid() { foreach (Transform children in transform) { int roundX = Mathf.RoundToInt(children.transform.position.x); int roundY = Mathf.RoundToInt(children.transform.position.y); grid[roundX, roundY] = children; // 今回の追加 // height-1 = 19のところまでブロックがきたらGameOver if (roundY >= height - 1) { // GameOverメソッドを呼び出す FindObjectOfType<GameManagement>().GameOver(); } } } |
GameOverメソッドはminoが積み上がったら、実行されるという設定です。
heightは20なのでheight – 1は19ですね。
minoがheight – 1を超えるとGameOverメソッドが呼び出されてテトリスがリロードするという処理です。
minoスクリプトとGameManagementスクリプトが長くなっていて、少し見づらいかもしれませんが、ご了承ください。
抜粋したところだけを載せるのも可能ですが、今回の記事から見た人がわかりづらいと思いすべてコードを載せることにしました。
Unityを勉強する
Udemyの動画で勉強する
個人的に、最初のUnityでの開発は動画を見ながら行うことをオススメします。
Udemyには初心者向けから中級者向けなどUnityを教えてくれる教材が揃っていて、割引期間だと数千円で講座を受講できます。
スペシャリストの方の講義が数千円で学べると思うと本当に安いと感心します。
実際に私もいくつかUdemyで課金をして色々学んでいます。
また、Udemyを使ったことがない方も30日返金保証もついているので安心して始めることができます。
まずはお試しで講座を受講してみましょう。
本で勉強する
この本はUnity学習者におすすめです。
内容がとても良くてイラストで重要なポイントは解説されているので、理解しやすいです。
操作する内容は画像付きなので、同じ操作しても同じ動作にならないというようなことはないように工夫されています。
一冊勉強するだけで、大量の知識をインプットできるので、テトリス作成と同時進行で試してみてください。
今回のまとめ
今回、GameOverとGameClearメソッドを追加して、ゲームオーバーでもクリアでも続けられるようになりました。
次回は、時間の制限を加えて60秒以内でclearScoreに到達しなければ、GameOverメソッドを実行する処理を追加します。
最後まで読んでいただきありがとうございました。
⭐️あわせて読もう!
→Unityテトリスの作り方-11
コメント