「並び替えの簡単なパズルゲーム(ソートゲーム)」を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; }