Unity6で「簡単なスライドパズルゲーム」を作成するPart2を進めていきます。今回は「タイルをクリックしたら移動」を実装していきます。
はじめに
前回の続きのPart2を作成していきます。Part1は下記から。
Part1ではタイル生成をスクリプトで作成しました。Part2では「タイルをクリックしたら移動」を実装していきます。
ゲーム作成開始
前回、数字順にタイル生成しました。まずは、8番のタイルをクリックしたら右のブランク位置に移動するのを実装していきます。

スクリプトを変更
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()
{
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;
}
}
}
public int MoveTileRight(int x,int y)
{
if (x < 2 && tiles[x + 1, y] == null)
{
tiles[x + 1, y] = tiles[x, y];
tiles[x, y] = null;
return 1;
}
return 0;
}
}
スクリプトの簡単な説明
- instance化して他のスクリプトから利用できるように。
- 配列にタイル情報を格納。初期配置では右下(x:2,y:0)がnullになります。
- MoveTileRightで右方向がnullの場合は配列内のデータを移動し、1(右方向の移動量)を返しています。
タイルスクリプトは下記のように変更します。
using UnityEngine;
public class Tile : MonoBehaviour
{
[SerializeField] private SpriteRenderer spriteNum;
private int xPos, yPos;
public void InitTile(Sprite sprite,int x,int y)
{
spriteNum.sprite = sprite;
UpdatePosition(x, y);
}
private void UpdatePosition(int x,int y)
{
xPos = x;
yPos = y;
transform.position = new Vector2(x, y);
}
private void OnMouseDown()
{
if (GameManager.instance.MoveTileRight(xPos,yPos) != 0)
{
UpdatePosition(xPos + 1, yPos);
}
}
}
スクリプトの簡単な説明
- xPos,yPosには現在の位置をセットしています(transform.positionの代わり)。
- OnMouseDownで右方向に移動できるかチェックして、移動できる場合は移動。
8をクリックして右に動いたら7もクリックして右に移動したらOKです。
上下左右に動くように変更
右移動しか実装していないので同じように上下左右に動くように変更します。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()
{
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;
}
}
}
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;
}
}
Tileスクリプトは下記に変更します。
using UnityEngine;
public class Tile : MonoBehaviour
{
[SerializeField] private SpriteRenderer spriteNum;
private int xPos, yPos;
public void InitTile(Sprite sprite,int x,int y)
{
spriteNum.sprite = sprite;
UpdatePosition(x, y);
}
private void UpdatePosition(int x,int y)
{
xPos = x;
yPos = y;
transform.position = new Vector2(x, y);
}
private void OnMouseDown()
{
int diffX = GameManager.instance.MoveTileLR(xPos, yPos);
int diffY = GameManager.instance.MoveTileUD(xPos, yPos);
if (diffX != 0 || diffY != 0)
{
UpdatePosition(xPos + diffX, yPos + diffY);
}
}
}
スクリプトはもう少しまとめることが出来ますが、何をしているのか分かりやすさ重視にしています。
実行して、下記のようにタイルをクリックして上下左右に動かすことが出来たらOKです。

