Unityで3マッチパズルを作りたい。
でも、判定や連鎖処理が複雑で、実装が難しい。
どこから手をつけていいか分からない。
Unityなら、配列管理と判定ロジックを組み合わせることで、3マッチパズルを実装できます。
この記事では、盤面管理から連鎖処理まで、実装の流れを解説していきます。
- 2次元配列での盤面管理とスワップ判定の実装
- 横方向・縦方向の3つ揃った判定のチェック方法
- 消去後のブロック落下処理の実装
- 再帰的な連鎖判定の実装方法
- Coroutineを使った落下アニメーションの実装
\パズルの次は!頭を使うゲームを自分で作ってみよう/
最初の1本目に最適
Unity タワーディフェンス
ゲームの作り方講座
敵の侵攻を防ぐ配置戦略がパズル脳に直結!全10回のコンパクトな構成で、初心者でもゲーム開発の全体像をつかめます。
スマホアプリを作りたい方へ
Unity 放置インフレ型
クリッカーゲームの作り方講座
数値が積み上がる快感はパズル好きに刺さる!スマホ対応・リリースレベルの放置系クリッカーを全12回で完成させられます。
思考系ゲームに挑戦
Unity ノンフィールドRPG
+スレスパ風JRPG講座
カードを選んで戦略を組み立てるデッキ構築はパズル脳との相性抜群。Unity6対応・スマホ化対応の最新カリキュラムで挑戦できます。
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
3マッチパズルの基本構造

3マッチパズルは、4つの要素で構成されています。
盤面を管理する配列、ピースを入れ替えるスワップ機能、3つ揃った判定、消去後の落下処理。
これらの要素が連携することで、ゲームとして成立するんです。
まずは、それぞれの要素がどのような役割を担っているか、理解しておきましょう。
| 要素 | 役割 | 実装方法 |
|---|---|---|
| 盤面管理 | グリッド上のピースの状態を管理 | 2次元配列(int[,]) |
| スワップ機能 | 2つのピースを入れ替える | 配列要素の交換 |
| 3つ判定 | 横・縦方向に3つ以上揃っているかチェック | ループと条件分岐 |
| 落下処理 | 消去後の空白を埋める | 配列の要素シフト |
この4つの要素を順番に実装していけば、3マッチパズルが完成します。
それぞれの実装方法を、詳しく見ていきましょう。
2次元配列で盤面を管理する

盤面の状態は、2次元配列で管理します。
配列の要素には、ピースの種類(色や形)を表す整数値を格納。
例えば、0が赤、1が青、2が緑といった感じです。
盤面のサイズは、配列のサイズで決定されます。
6×6の盤面なら、6×6の配列を用意します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public class Match3Board : MonoBehaviour { public int width = 6; public int height = 6; public int[,] board; // 2次元配列で盤面を管理 void Start() { board = new int[width, height]; InitializeBoard(); } void InitializeBoard() { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // ランダムにピースを配置(0〜4の種類) board[x, y] = Random.Range(0, 5); } } } } |
2次元配列のインデックスは、[x, y]の順番で指定。
最初のインデックスがX座標(横)、2番目がY座標(縦)を表します。
この配列を使って、盤面の状態を管理していきます。
スワップ機能の実装

ピースを入れ替えるには、Swap関数で配列要素を交換します。
2つの座標を指定して、それぞれの位置にあるピースの値を入れ替えるだけ。
単純な処理ですが、3マッチパズルの核心となる機能です。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
void SwapPieces(int x1, int y1, int x2, int y2) { // 配列の範囲チェック if (x1 < 0 || x1 >= width || y1 < 0 || y1 >= height) return; if (x2 < 0 || x2 >= width || y2 < 0 || y2 >= height) return; // 一時変数を使って値を交換 int temp = board[x1, y1]; board[x1, y1] = board[x2, y2]; board[x2, y2] = temp; } |
Swap関数は、配列の範囲外アクセスを防ぐためのチェックも重要。
範囲外の座標が指定されたら、処理を中断します。
スワップ後は、3つ揃った判定を実行する流れです。
3つ揃った判定の実装

3つ以上同じピースが揃っているかチェックするには、横方向と縦方向の両方を確認します。
ループを使って、連続する同じピースの数をカウント。
3つ以上連続していれば、マッチ成立です。
まずは、横方向の判定から見てみましょう。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
List<Vector2Int> CheckMatches() { List<Vector2Int> matches = new List<Vector2Int>(); HashSet<Vector2Int> processed = new HashSet<Vector2Int>(); // 横方向の判定 for (int y = 0; y < height; y++) { int count = 1; int currentType = board[0, y]; for (int x = 1; x < width; x++) { if (board[x, y] == currentType) { count++; } else { // 3つ以上連続していたらマッチ if (count >= 3) { for (int i = x - count; i < x; i++) { Vector2Int pos = new Vector2Int(i, y); if (!processed.Contains(pos)) { matches.Add(pos); processed.Add(pos); } } } count = 1; currentType = board[x, y]; } } // 行の最後までチェック if (count >= 3) { for (int i = width - count; i < width; i++) { Vector2Int pos = new Vector2Int(i, y); if (!processed.Contains(pos)) { matches.Add(pos); processed.Add(pos); } } } } // 縦方向の判定も同様に実装 return matches; } |
横方向と縦方向、両方の判定を実装する必要があります。
縦方向の判定も、同じロジックで実装できます。
マッチしたピースの座標をリストに保存し、後で消去処理に使います。

消去後のブロック落下処理

ピースを消去した後、上のピースを落下させて空白を埋めます。
列ごとに処理を行い、空白(または特定の値)を上に移動させていきます。
配列操作で実現できますが、少し複雑な処理です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
void RemoveMatches(List<Vector2Int> matches) { // マッチしたピースを消去(-1で空白を表す) foreach (Vector2Int pos in matches) { board[pos.x, pos.y] = -1; } // 各列ごとに落下処理 for (int x = 0; x < width; x++) { // 下から上に順番に見ていき、空白を見つける for (int y = 0; y < height; y++) { if (board[x, y] == -1) // 空白 { // 上のピースを下に移動 for (int y2 = y + 1; y2 < height; y2++) { board[x, y2 - 1] = board[x, y2]; } // 一番上に新しいピースを生成 board[x, height - 1] = Random.Range(0, 5); } } } } |
落下処理は、列ごとに下から順に処理していくのがポイント。
空白を見つけたら、その上のピースを1つずつ下に移動。
一番上に新しいピースを生成すれば、落下処理が完了します。
連鎖処理の実装

落下後に新しく3つ揃ったら、連鎖として処理します。
連鎖処理は、再帰的に判定を呼び出す方法で実装。
マッチが見つからなくなるまで、繰り返し処理を実行します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
IEnumerator ProcessMatches() { bool foundMatch = true; while (foundMatch) { // マッチをチェック List<Vector2Int> matches = CheckMatches(); if (matches.Count > 0) { // マッチしたピースを消去 RemoveMatches(matches); // 落下アニメーションを待つ yield return StartCoroutine(AnimateFalling()); // 再チェックのため、ループを続ける foundMatch = true; } else { foundMatch = false; } } } |
Coroutineを使って、アニメーションを待ちながら処理を進めます。
マッチが見つからなくなるまで、繰り返し処理を実行。
これにより、連鎖が自然に発生します。
Coroutineで落下アニメーションを実装する

ピースの落下を滑らかに見せるには、Coroutineでアニメーションを実装します。
Transform.positionを徐々に変更することで、滑らかな動きを実現。
全てのピースの落下が完了するまで待つ処理も重要です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
IEnumerator AnimateFalling() { // 落下が必要なピースを特定 Dictionary<GameObject, Vector3> fallingPieces = new Dictionary<GameObject, Vector3>(); // 各ピースの目標位置を計算 for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { GameObject piece = GetPieceAt(x, y); if (piece != null) { Vector3 targetPos = GridToWorldPosition(x, y); if (piece.transform.position != targetPos) { fallingPieces.Add(piece, targetPos); } } } } // アニメーション実行 float duration = 0.3f; float elapsed = 0f; while (elapsed < duration) { elapsed += Time.deltaTime; float t = elapsed / duration; foreach (var kvp in fallingPieces) { GameObject piece = kvp.Key; Vector3 startPos = piece.transform.position; Vector3 endPos = kvp.Value; piece.transform.position = Vector3.Lerp(startPos, endPos, t); } yield return null; } // 最終位置に確実に配置 foreach (var kvp in fallingPieces) { kvp.Key.transform.position = kvp.Value; } } |
Vector3.Lerpで線形補間を行い、滑らかな移動を実現。
アニメーション時間内に、開始位置から終了位置まで徐々に移動します。
アニメーションが完了したら、連鎖判定を再実行します。
実装手順の全体像

ここまで説明した内容を、実装手順として整理しましょう。
- STEP1盤面管理の実装
2次元配列で盤面の状態を管理するクラスを作成します。盤面の初期化と、ピースの種類をランダムに配置する処理を実装します。
- STEP2スワップ機能の実装
2つのピースを入れ替えるSwap関数を実装します。配列の範囲チェックも忘れずに実装しておきましょう。
- STEP33つ判定の実装
横方向・縦方向の両方で、3つ以上同じピースが連続しているかチェックする処理を実装します。マッチしたピースの座標をリストに保存します。
- STEP4消去処理の実装
マッチしたピースを消去し、上のピースを落下させる処理を実装します。列ごとに処理を行うのがポイントです。
- STEP5落下アニメーションの実装
Coroutineを使って、ピースの落下を滑らかにアニメーションする処理を実装します。Vector3.Lerpを使って線形補間を行います。
- STEP6連鎖処理の実装
落下後に新しく3つ揃ったら、再帰的に処理を繰り返す連鎖システムを実装します。マッチが見つからなくなるまで処理を続けます。
この順番で実装すれば、3マッチパズルが完成します。
順番を間違えると、後で大幅な修正が必要になるので注意。
配列操作と座標変換のポイント

3マッチパズルでは、配列操作が頻繁に発生します。
配列のインデックスと、画面上の座標の変換が必要な場面も多いです。
座標変換のためのヘルパー関数を作っておくと、コードが読みやすくなります。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// グリッド座標からワールド座標へ変換 Vector3 GridToWorldPosition(int x, int y) { float worldX = x * cellSize; float worldY = y * cellSize; return new Vector3(worldX, worldY, 0); } // ワールド座標からグリッド座標へ変換 Vector2Int WorldToGridPosition(Vector3 worldPos) { int gridX = Mathf.RoundToInt(worldPos.x / cellSize); int gridY = Mathf.RoundToInt(worldPos.y / cellSize); return new Vector2Int(gridX, gridY); } |
座標変換のロジックを関数化しておけば、後で調整しやすくなります。
cellSizeは、1マスのサイズを表す変数。
この値を調整すれば、盤面の大きさを変更できます。
デバッグ時の可視化方法

3マッチパズルの実装中、配列の状態を可視化すると便利。
OnDrawGizmosやDebug.Logを使って、盤面の状態を確認しましょう。
マッチ判定が正しく動作しているか、落下処理が適切か、視覚的に確認できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
void OnDrawGizmos() { if (board == null) return; // 盤面の各マスを描画 for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Vector3 pos = GridToWorldPosition(x, y); Gizmos.color = GetColorForPiece(board[x, y]); Gizmos.DrawCube(pos, Vector3.one * cellSize * 0.8f); } } } Color GetColorForPiece(int pieceType) { switch (pieceType) { case 0: return Color.red; case 1: return Color.blue; case 2: return Color.green; case 3: return Color.yellow; case 4: return Color.magenta; default: return Color.white; } } |
Gizmosを使えば、エディタ上で盤面の状態を確認できます。
実行しなくても、配列の内容を視覚的に確認できるので、デバッグが楽になります。
- 配列のインデックスを[x, y]ではなく[y, x]にして、座標がずれる
- 落下処理で、下から上ではなく上から下に処理してしまい、正しく落下しない
- 連鎖判定を忘れて、落下後に新しくマッチしても消去されない
これらのポイントに注意すれば、スムーズに実装できます。
パズルゲームが好きなら!頭を使うゲームを自分で作る楽しさを体験しよう
パズルゲームが好きな人は、ゲームの仕組みや戦略を考えるのが得意です。その思考力はゲーム開発にそのまま活かせます。配置・戦略・ロジック設計が楽しめる講座を紹介します。
Unity タワーディフェンスゲームの作り方講座【全10回!配置戦略が楽しい初心者最初の1本!】

- 敵の侵攻ルートを読んで砲台を配置する戦略性がパズル脳に直結
- 全10回のコンパクトな構成で初心者でもゲーム開発の全体像をつかめる
- 敵AI・ステージ設計・アイテムショップ・レベルデザインまで習得
- 丁寧な解説とソースコード付きでサクサク進められる
Unity タワーディフェンスゲームの作り方講座は、敵の侵攻を防ぐために砲台をどこに配置するかを考える戦略性がパズル好きの思考回路と直結するジャンルです。
全10回というコンパクトな構成で、敵AI・ステージ設計・アイテムショップ・レベルデザインまで習得できます。「最初の1本目」として最もおすすめできる入門講座です。
パズルを解く感覚でゲームを作る第一歩を踏み出したい人に、自信を持っておすすめできる一本です。
全10回・配置戦略が楽しいタワーディフェンスをゼロから作る
まず1本完成させてゲーム開発の楽しさを体験しよう
→ タワーディフェンスゲームの作り方講座を見てみる
コンパクトな10回で完成!ゲーム開発の全体像を一気につかもう!
Unity 放置インフレ型クリッカーゲームの作り方講座【全12回!スマホアプリとしてリリースできるレベルのゲームを作れる!】

- 数値が積み上がる快感と段階的な要素解放がパズル好きに刺さる
- スマホ対応・リリースレベルのクリッカーゲームを全12回で完成
- ScriptableObjectやInterfaceなど実践で使えるUnity中級スキルも習得
- セーブ・ロード機能・サウンド実装まで本格的な構成
Unity 放置インフレ型クリッカーゲームの作り方講座は、数値が積み上がる快感・段階的な要素の解放・最適化の楽しさがパズルゲームと相性抜群のジャンルです。
単純なカウンターゲームではなく、本格的な放置系クリッカーゲームをスマホ対応でリリースレベルまで作り上げます。講座専用素材付きで、ダウンロードしてすぐに開発をスタートできます。
「自分で作ったアプリをスマホでプレイしたい!」という人の夢を全12回で叶えられる講座です。
スマホ対応・リリースレベルの放置系クリッカーを完成させる
数値が積み上がる快感をゲームで自分の手で作り上げよう
→ クリッカーゲームの作り方講座を見てみる
スマホで動く自分だけのクリッカーゲームを今すぐ作り始めよう!
Unity ノンフィールドRPG+スレスパ風JRPG講座【Unity6対応!カード戦略×JRPGで思考系ゲームを作れる!】

- カードを選んで戦略を組み立てるデッキ構築がパズル脳と相性抜群
- Unity6対応・スマホ化対応で最新環境のゲーム開発が学べる
- Slay the Spire風のゲームロジック設計を楽しみながら習得
- ノンフィールドRPGとデッキ構築JRPGの2つを合わせて学ぶのがおすすめ
Unity ノンフィールドRPGの作り方講座+Slay the Spire風デッキ構築JRPGの作り方講座は、手札から最適なカードを選んで戦略を組み立てるデッキ構築システムを実装できる講座です。
「どのカードを引いてどう組み合わせるか」を考える思考プロセスはパズルゲームと同じ脳の使い方。Unity6対応・スマホ化対応の最新カリキュラムで、思考系ゲームの設計を楽しみながら学べます。
タワーディフェンス・クリッカーで開発に慣れたら、次のステップとして挑戦したい一本です。
カード戦略×JRPGで思考系ゲームの設計を学ぶ
トレンドのデッキ構築システムをスマホ向けに実装しよう
→ スレスパ風デッキ構築JRPG講座を見てみる
パズル脳を活かしたゲーム設計で、一歩上のゲーム開発スキルを身につけよう!
まとめ

この記事では、Unityで3マッチパズルを実装する方法について解説しました。
- 2次元配列で盤面の状態を管理し、ピースの種類を整数値で表現する
- スワップ機能で配列要素を交換し、3つ判定で連続する同じピースを検出する
- 消去後の落下処理を列ごとに実装し、空白を上から埋めていく
- 連鎖処理は再帰的に判定を呼び出し、マッチが見つからなくなるまで処理を繰り返す
- Coroutineで落下アニメーションを実装し、滑らかな動きを実現する
まずは簡単な盤面サイズから始めて、動作を確認しながら機能を追加していきましょう。
配列操作と座標変換の考え方を覚えておけば、他のパズルゲームでも応用できます。
さらに高度な機能に挑戦する時は、専門の教材を活用するのがおすすめです。
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。





コメント