Unity|並び替えパズルゲーム(ソートゲーム)。Part2.指定位置へ移動・クリア判定

「並び替えの簡単なパズルゲーム(ソートゲーム)」をUnityで作成、第2回目です。

はじめに

Part1は下記です。

今回やること

パート1では「ボールの生成」と「ボールの移動」を仮で作成しました。今回は動きを整えて、ゲームクリアを作成していきます。

作成開始

まずはクリックで選択した瓶にボールを移動するようにします。

BottleにBoxCollider2Dをアタッチして、コライダーのサイズを瓶に合わせます。

新規でスクリプトを作成、名前をGameManagerとします。

using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance { get; private set; }

    public List<Bottle> bottles;
    private int ChoiceBottleNo = -1;

    private void Start()
    {
        Instance = this;
    }
    public void ClickBottle(int bottleNo)
    {
        if (ChoiceBottleNo == -1)
        {
            ChoiceBottleNo = bottleNo;
        }
        else
        {
            if (ChoiceBottleNo != bottleNo)
            {
                bottles[ChoiceBottleNo].MoveBall(bottles[bottleNo]);
            }
            ChoiceBottleNo = -1;
        }
    }
}

スクリプトの簡単な説明

  • 初めにクリックした瓶の番号をChoiceBottleNoに保存、次に違う瓶がクリックされたらボールを移動します

クリックした瓶に移動

空オブジェクトを追加して、名前をGameManagerに変更。スクリプトをアタッチして、パラメータにbottleをセットします。

Bottleスクリプトを下記に変更します。まずはボール1個だけで動く形で作成。

using UnityEngine;

public class Bottle : MonoBehaviour
{
    [SerializeField] private GameObject[] ballPrefab;
    [SerializeField] private Transform balls;
    [SerializeField] private int BottleNo;

    private GameObject ball;

    void Start()
    {
        for (int i = 0; i < ballPrefab.Length; i++)
        {
            ball = Instantiate(ballPrefab[i], balls);
            ball.transform.position = new Vector3(0, -1.5f + i);
        }
    }

    private void OnMouseDown()
    {
        GameManager.Instance.ClickBottle(BottleNo);
    }

    public void MoveBall(Bottle bottleRef)
    {
        ball.transform.parent = bottleRef.balls;
        ball.transform.position = new Vector3(2.0f, -1.5f);
    }
}

下記のようにボトル番号をセットします。

さらにBottleスクリプトを下記に変更します。複数個のボールがボトル内にある場合の対応です。

using System.Collections.Generic;
using UnityEngine;

public class Bottle : MonoBehaviour
{
    [SerializeField] private GameObject[] ballPrefab;
    [SerializeField] private Transform ballPosition;
    [SerializeField] private int BottleNo;
    
    public List<GameObject> balls;

    private float yDistance = -1.5f;

    void Start()
    {
        for (int i = 0; i < ballPrefab.Length; i++)
        {
            GameObject ball = Instantiate(ballPrefab[i], ballPosition);
            ball.transform.position = new Vector3(transform.position.x, yDistance + i);
            balls.Add(ball);
        }
    }

    private void OnMouseDown()
    {
        GameManager.Instance.ClickBottle(BottleNo);
    }

    public void MoveBall(Bottle bottleRef)
    {
        int index = balls.Count - 1;
        int i = bottleRef.balls.Count;

        balls[index].transform.parent = bottleRef.ballPosition;
        balls[index].transform.position = new Vector3(bottleRef.transform.position.x, yDistance + i);

        bottleRef.balls.Add(balls[index]);
        balls.RemoveAt(index);
    }
}

bottleをコピーして追加してBottleNoをセット。、GameManagerにBottleをセットします。

ボールのプレハブを複製、青色のボールを作成します。tagを「BLUE」にします。

ボールを下記のようにセットしてみます。

実行すると下記のような感じに。

これで一応、ゲームの形が完成。実際には見た目のほかに、瓶やボールの数を変えて複数のステージを作成したり。

チェック追加・クリア判定

移動前の瓶の中にボールが0個、または移動後の瓶の中にボールが4個ある場合のチェック、ゲームクリアをすると下記のような感じに。

    public void MoveBall(Bottle bottleRef)
    {
        if (balls.Count == 0) return;
        if (bottleRef.balls.Count == 4) return;

        int index = balls.Count - 1;
        int i = bottleRef.balls.Count;

        balls[index].transform.parent = bottleRef.ballPosition;
        balls[index].transform.position = new Vector3(bottleRef.transform.position.x, yDistance + i);

        bottleRef.balls.Add(balls[index]);
        balls.RemoveAt(index);

        if (GameManager.Instance.GameClearCheck())
        {
            Debug.Log("Game CLEAR");
        }
    }

GameManagerに下記を追加。ボール移動後に下記を呼び出してゲームクリアチェックを行います。

    public bool GameClearCheck()
    {
        bool ClearFlag = true;

        foreach (Bottle bottle in bottles)
        {
            if (bottle.balls.Count == 0) continue;

            if (bottle.balls.Count < 4)
            {
                ClearFlag = false;
                break;
            }

            bool tagcheck = true;
            var tag = bottle.balls[0].tag;
            foreach (GameObject ball in bottle.balls)
            {
                if (!ball.CompareTag(tag))
                {
                    tagcheck = false;
                    break;
                }
            }
            if (!tagcheck)
            {
                ClearFlag = false;
                break;
            }
        }
        return ClearFlag;
    }
タイトルとURLをコピーしました