Unityテトリスの作り方-10

※当サイトはアフィリエイト広告を使用しています。

テトリス作成

こんにちは、マサです。

前回はスコアを表示させるところまでやりました。

今回は、minoが上まで積み上がるとゲームオーバーでリスタートするのと、

スコアが1500になるとゲームがクリアしてリスタートするという処理を追加します。

スポンサーリンク

GameOverとGameClearメソッドを追加

まずは、コードをすべて載せます。
確認しつつ、どういう処理になっているのか?確認しましょう。

※今回追加したコードは”//今回の追加“と記載してます

GameManagementスクリプト

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スクリプト

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;の追加

// 今回の追加
using UnityEngine.SceneManagement;

 

Sceneの移動や切り替えやリロードの時に必要になります。
使い方は色々あるので、Unityのリファレンスを見るとより詳しく説明されています。

GameClearとGameOverメソッドを追加

    // スコア関連
    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メソッドが呼び出されて、リロードするという処理にしました。

    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

コメント

タイトルとURLをコピーしました