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