Unity6で「簡単なスライドパズルゲーム」を作成するPart3を進めていきます。今回は「初期タイルのシャッフル」と「ゲームクリアの判定」を実装していきます。今回で仮の完成形となります。
はじめに
今回は第3回目です。第1回目は下記から。
Part1では「タイルの生成をスクリプトで作成」、Part2では「タイルをクリックしたら移動」を実装しました。Part3では「初期配置タイルのシャッフルとゲームクリアの判定」を実装していきます。
ゲーム作成開始
まずは簡単なシャッフルを行い、ゲームクリアの最終形を実装していきます。
タイルをシャッフル
タイルのシャッフルは完全ランダムに配置すると完成できない可能性があるので、初期配置(完成状態)した後にタイルクリックをランダムに行い実装します。(もちろん、他にも方法はたくさんあります)
下記はシャッフル部分だけのスクリプトです、100回ランダムにタイルのクリックをシミュレートしています。
private void ShuffleTile()
{
for (int k = 0; k < 100; k++)
{
int x = Random.Range(0, 3);
int y = Random.Range(0, 3);
if (tiles[x, y] != null)
{
tiles[x, y].OnMouseDownSimulate();
}
}
}
ゲームクリアの実装(最終的なスクリプト)
最終的なTileスクリプトを下記のように変更します。
using UnityEngine;
public class Tile : MonoBehaviour
{
[SerializeField] private SpriteRenderer spriteNum;
private int xPos, yPos;
private Vector2 rightPosition;
private Vector2 currentPosition;
public bool isRightTile = true;
public void InitTile(Sprite sprite,int x,int y)
{
spriteNum.sprite = sprite;
UpdatePosition(x, y);
rightPosition = new Vector2(x, y);
}
private void UpdatePosition(int x,int y)
{
xPos = x;
yPos = y;
transform.position = new Vector2(x, y);
currentPosition = new Vector2(x, y);
if (rightPosition == currentPosition)
isRightTile = true;
else
isRightTile = false;
}
public void OnMouseDownSimulate()
{
TileMoveCheck();
}
private void OnMouseDown()
{
TileMoveCheck();
GameManager.instance.CheckClear();
}
private void TileMoveCheck()
{
int diffX = GameManager.instance.MoveTileLR(xPos, yPos);
int diffY = GameManager.instance.MoveTileUD(xPos, yPos);
if (diffX != 0 || diffY != 0)
{
UpdatePosition(xPos + diffX, yPos + diffY);
}
}
}
スクリプトの簡単な説明
- isRightTileにタイルの位置が正しい位置(シャッフル前の初期位置)を格納
- 位置を変更したときにタイル位置が正しいか判断、マウスクリックして移動判定後にクリア判定
GameManagerスクリプトを下記に変更します。
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager instance { get; private set; }
[SerializeField] private Tile tilePrefab;
[SerializeField] private Sprite[] sprite;
[SerializeField] private Tile[,] tiles = new Tile[3, 3];
private void Awake()
{
instance = this;
}
void Start()
{
SetTile();
ShuffleTile();
}
private void SetTile()
{
int i = 0;
for (int y = 2; y >= 0; y--)
{
for (int x = 0; x < 3; x++)
{
Tile obj = Instantiate(tilePrefab, new Vector3(x, y), Quaternion.identity);
obj.InitTile(sprite[i], x, y);
tiles[x, y] = obj;
i++;
if (i >= 8) break;
}
}
}
private void ShuffleTile()
{
for (int k = 0; k < 100; k++)
{
int x = Random.Range(0, 3);
int y = Random.Range(0, 3);
if (tiles[x, y] != null)
{
tiles[x, y].OnMouseDownSimulate();
}
}
}
public int MoveTileLR(int x,int y)
{
//Right
if (x < 2 && tiles[x + 1, y] == null)
{
tiles[x + 1, y] = tiles[x, y];
tiles[x, y] = null;
return 1;
}
//Left
if (x >0 && tiles[x - 1, y] == null)
{
tiles[x - 1, y] = tiles[x, y];
tiles[x, y] = null;
return -1;
}
return 0;
}
public int MoveTileUD(int x, int y)
{
//Up
if (y < 2 && tiles[x, y+1] == null)
{
tiles[x, y+1] = tiles[x, y];
tiles[x, y] = null;
return 1;
}
//Down
if (y > 0 && tiles[x, y-1] == null)
{
tiles[x, y-1] = tiles[x, y];
tiles[x, y] = null;
return -1;
}
return 0;
}
public void CheckClear()
{
int correctTile = 0;
for (int y = 2; y >= 0; y--)
{
for (int x = 0; x < 3; x++)
{
if (tiles[x, y] != null)
{
if (tiles[x, y].isRightTile)
correctTile++;
}
}
}
if (correctTile == 8)
Debug.Log("GameClear");
}
}
スクリプトの簡単な説明
- タイルを初期配置した後にシャッフル(タイルクリックをシミュレート)
- 各タイルが正しい位置の場合(8枚が正しい位置)、ゲームクリア
実行して、タイルを正しい位置に動かした時にコンソールに「GameClear」が表示されたら完成。
おまけ
下記のように好きな画像を分割してセットすることもできます。

下記のような感じになります。

後はゲームの開始画面、終了画面の作成。分割数を増やしたりするのも良いですね。分かりやすく座標と配列を合わせた形で作成していますが、計算して算出するなどスクリプトの変更したほうが良い箇所も結構ありますね。
