はじめに
こんにちは!今回も シャドウバース風の2Dカードゲーム を作っていきます。前回のパート3では、以下の機能を実装しましたね。
- カードを手札に生成 する
- ドラッグ&ドロップでフィールドに移動 できるようにする
- 両プレイヤーに3枚ずつカードを配る
これで、ゲームの基本的なカード配置ができるようになりました。しかし、まだカードを出した後の動きがありませんよね。
そこで今回の パート4 では、ゲームに「ターン制」を実装していきます!
今回の実装内容
- ターンの切り替え
- プレイヤーと敵のターンを交互に切り替える
- ターンエンドボタン を押すと次のターンへ進む
- ドロー機能の追加
- ターン開始時にカードを1枚ドロー する
- 敵の行動を実装
- 敵のターンになったらカードを1枚フィールドに出す
- 最初はシンプルな動作ですが、今後のAI実装の基礎になります!
このパートを終えると、ターンごとに手札が増え、敵も自動でカードを出せるようになります。シンプルですが、カードゲームらしくなってきますね!
それでは、早速 ターン制の実装 から始めていきましょう!
1. ターン制の実装
カードゲームには、プレイヤーと敵が交互に行動するターン制が必要です。ここでは、ターンエンドボタンを押すとターンが切り替わる仕組みを作っていきます。
1-1. GameManagerにターン制のコードを追加
まず、ゲームの管理を行う GameManager スクリプトを開き、以下のコードを追加します。
using UnityEngine;
public class GameManager : MonoBehaviour
{
// プレイヤーのターンかどうかを判定する変数
bool isPlayerTurn;
void Start()
{
StartGame();
isPlayerTurn = true; // ゲーム開始時はプレイヤーのターン
TurnCalc();
}
void TurnCalc()
{
// ターン進行の処理
if (isPlayerTurn)
{
PlayerTurn();
}
else
{
EnemyTurn();
}
}
void PlayerTurn()
{
// プレイヤーのターン開始時の処理
Debug.Log("プレイヤーのターンです");
}
void EnemyTurn()
{
// 敵のターン開始時の処理
Debug.Log("敵のターンです");
// 何もせずにターンを終了する
ChangeTurn();
}
public void ChangeTurn()
{
// ターンを切り替える
isPlayerTurn = !isPlayerTurn;
TurnCalc();
}
}
1-2. ターンの切り替え処理の解説
上記のスクリプトでは、ターン制をシンプルに実装しています。
✅ isPlayerTurntrue
のときプレイヤーのターン、false
のとき敵のターンになります。
✅ Start() メソッド
ゲーム開始時に StartGame()
を実行し、最初に isPlayerTurn
を true
に設定。続いて TurnCalc()
を呼び出し、最初のターンを開始します。
✅ TurnCalc() メソッド
現在のターンを判定し、プレイヤーのターンなら PlayerTurn()
、敵のターンなら EnemyTurn()
を実行します。
✅ ChangeTurn() メソッドisPlayerTurn
の値を反転させて (true → false
、false → true
) ターンを切り替え、TurnCalc()
を再実行します。
1-3. ターンエンドボタンの設定
次に、プレイヤーがターンを終了できるように、ボタンを設定 します。
- Canvas内に「Button」を作成
GameObject
→UI
→Button
を選択し、名前をTurnEndButton
に変更Text
をターンエンド
に変更
- ボタンの
OnClick
にGameManager
のChangeTurn()
を設定TurnEndButton
の Inspector を開くOnClick()
のリストに GameManager をドラッグ&ドロップChangeTurn()
を選択
1-4. 実行結果の確認
ここまでの設定が完了したら、ゲームを実行してみましょう。
✅ ゲーム開始時の動作
- コンソールに「プレイヤーのターンです」と表示
- プレイヤーがターンエンドボタンを押すと
ChangeTurn()
が実行される
✅ ターンエンドボタンを押す
- コンソールに「敵のターンです」と表示
- すぐに
ChangeTurn()
が呼ばれ、再びプレイヤーのターンに戻る
✅ 敵のターンは何もしない
- 現状では、敵のターンでは特にアクションを起こさず、すぐにターンエンド
- 次回以降のステップで 敵の行動を追加 する

まとめ
🔹 ターン制の基本を実装(プレイヤーと敵が交互に行動)
🔹 ターンエンドボタンを押すとターンが切り替わる
🔹 デバッグログでターンの切り替わりを確認

次のステップでは、ターンごとにカードをドローする処理 を追加して、ターンの流れをよりゲームらしくしていきます!
2. ドローの実装
カードゲームにおいて、ターンごとにカードを引く「ドロー」機能は非常に重要です。ここでは、ターンが切り替わるタイミングで手札にカードを追加する処理 を実装していきます。
2-1. ドロー処理をGameManagerに追加
現在の GameManager
では、ターンが切り替わると プレイヤーのターンか敵のターンかを判定 し、それに応じた処理を実行しています。
ここにターン開始時に1枚カードをドローする処理 を追加します。
① GameManagerの ChangeTurn() を修正
まず、ChangeTurn()
関数にドロー処理を追加しましょう。
public void ChangeTurn()
{
// ターンの切り替え処理
isPlayerTurn = !isPlayerTurn;
if (isPlayerTurn)
{
// プレイヤーのターン開始時にカードをドロー
CreateCard(PlayerHandTransform);
}
else
{
// 敵のターン開始時にカードをドロー
CreateCard(EnemyHandTransform);
}
// 次のターンの処理を開始
TurnCalc();
}
② CreateCard()
とは?
CreateCard()
は、手札に新しいカードを生成する関数です。
この関数を使い、プレイヤーターンなら PlayerHandTransform
に、敵ターンなら EnemyHandTransform
にカードを追加します。
void CreateCard(Transform hand)
{
// 手札にカードを生成
CardController card = Instantiate(cardPrefab, hand, false);
// カードIDを指定(例: Card1)
card.Init(1);
}
この関数によって、ターンごとに 手札に1枚カードが追加される 仕組みになりました。
2-2. ドロー機能の動作確認
① Unity上での設定
GameManager
を空のオブジェクトにアタッチ- Inspectorで
PlayerHandTransform
とEnemyHandTransform
を設定 - ターンエンドボタンに
ChangeTurn()
を設定
② 実行テスト
- ゲームを開始すると、プレイヤーのターンが開始
- ターンエンドボタンを押すと、敵のターンに切り替わる
- ターン開始時に、それぞれの手札に1枚ずつカードが追加される
2-3. カードをランダムにドローする
現在の実装では、毎回 同じカード(Card1) をドローしています。
これを ランダムに異なるカードをドローするように変更 しましょう。
① CreateCard() を変更
void CreateCard(Transform hand)
{
// 1〜3の範囲でランダムなカードIDを設定
int randomCardID = Random.Range(1, 4);
// 手札にカードを生成
CardController card = Instantiate(cardPrefab, hand, false);
// ランダムなカードを設定
card.Init(randomCardID);
}
この修正により、ドローされるカードの種類が 毎回ランダムに変わる ようになります。
2-4. ドロー処理のカスタマイズ
① 手札の上限を設定
現在の状態では 無限にカードを引くことが可能 ですが、手札の上限を設定することで、よりゲームらしくなります。
例えば、手札の上限を 5枚まで に制限する場合は、次のように修正します。
void CreateCard(Transform hand)
{
// 手札が5枚未満ならカードを追加
if (hand.childCount < 5)
{
int randomCardID = Random.Range(1, 4);
CardController card = Instantiate(cardPrefab, hand, false);
card.Init(randomCardID);
}
else
{
Debug.Log("手札が上限に達しています!");
}
}
まとめ
- ターンが切り替わるごとに1枚カードをドローする処理を実装
- ターンエンド時にプレイヤーまたは敵の手札にカードを追加
- ランダムなカードをドローする機能を追加
- 手札の上限を設定することで、無限ドローを防止

この機能により、ゲームの戦略性が増し、より実用的なターン制バトル に近づきました!
次のステップでは 敵がカードをプレイできるようにし、よりゲームらしくしていきます!
3. 敵がカードを出せるようにする
カードゲームでは、プレイヤーだけでなく敵もカードをプレイできる必要があります。ここでは、敵のターンに手札からカードをフィールドに出す処理 を追加していきます。
3-1. カードの移動機能を追加する
まず、敵のカードを手札からフィールドに移動できるようにするために、CardMovementスクリプト に新しい関数を作成します。
CardMovement.cs
新しく以下の関数を追加します。
// 手札からフィールドにカードの位置を変更する
public void SetCardTransform(Transform parentTransform)
{
defaultParent = parentTransform; // 新しい親(フィールド)を設定
transform.SetParent(defaultParent, false); // 親オブジェクトを変更
}
この関数を呼び出せば、指定した Transform
にカードを移動できるようになります。
3-2. CardControllerにCardMovementを追加
次に、CardControllerスクリプト に CardMovement
を取得する処理を追加します。
CardController.cs
// カードの移動を管理するための変数を追加
public CardMovement movement;
private void Awake()
{
movement = GetComponent<CardMovement>();
}
これにより、カードの移動操作をCardControllerから制御できるように なります。
3-3. GameManagerで敵がカードを出す処理を追加
次に、GameManagerスクリプト に敵がカードを出す処理を実装します。
GameManager.cs
以下のコードを EnemyTurn()
に追加しましょう。
void EnemyTurn()
{
// 敵のターン開始時の処理
Debug.Log("敵のターンです");
// 敵の手札にあるカードリストを取得
CardController[] cardList = EnemyHandTransform.GetComponentsInChildren<CardController>();
if (cardList.Length > 0)
{
// 1枚目のカードをフィールドに出す
CardController card = cardList[0];
// カードをフィールドに移動
card.movement.SetCardTransform(EnemyFieldTransform);
Debug.Log("敵がカードをフィールドに出しました");
}
else
{
Debug.Log("敵の手札がありません");
}
// ターンを終了する
ChangeTurn();
}
この処理では、以下の動作を行います。
- 敵の手札(EnemyHandTransform)にあるカードを取得
- 手札にカードがあれば、一番最初のカードを選択
- そのカードを敵のフィールド(EnemyFieldTransform)に移動
- 「敵がカードをフィールドに出しました」とログを出力
- ターンを終了
3-4. スクリプトを適用する
ここまで作成したスクリプトを適用するために、GameManagerのInspectorで設定を確認 しましょう。
GameManagerの設定
- EnemyHandTransform → 敵の手札エリアの
Transform
を設定 - EnemyFieldTransform → 敵のフィールドエリアの
Transform
を設定
カードPrefabの設定
- CardController に CardMovement が正しくアタッチされていることを確認
- CardMovementの
defaultParent
が正しく更新されることを確認
3-5. ゲームを実行して確認
- ゲームを開始するとプレイヤーのターンが開始
- ターンエンドボタンを押すと敵のターンへ
- 敵の手札にカードがあれば、1枚フィールドに移動
- 敵のターンが終了し、プレイヤーのターンに戻る

これで、敵がターンごとに1枚カードを出すシンプルなAI が完成しました!
3-6. 敵の動きを強化するには?
現在の敵のAIは 「手札の最初のカードを1枚出すだけ」 というシンプルなものですが、以下の方法でさらに進化させることができます。
✅ ランダムなカードを選んで出す
int index = Random.Range(0, cardList.Length);
CardController card = cardList[index];
敵が手札の中からランダムにカードを選ぶようになります。
✅ 特定の条件を満たしたときにカードを出す
- コスト管理を追加し、出せるカードがあるか判定
- プレイヤーのカード状況に応じて行動を変える
- カードの種類(攻撃系・防御系)に応じた選択をする
✅ 複数枚のカードを出す
- 1ターンに 2枚以上のカードを出せるようにする
for
ループを使って、複数のカードをプレイ可能
まとめ
これで、シャドウバース風の2Dカードゲームのターン制を実装 することができました!
今回のパートでは、以下の3つの機能を追加しました。
✅ ターンの切り替え処理
✅ ターンごとにカードをドローする処理
✅ 敵がカードをフィールドに出すシンプルなAI
学んだポイント
- ボタンを使ってターンを切り替える
isPlayerTurn
を使ってプレイヤーと敵のターンを管理。ChangeTurn()
を呼び出すことで、ターンが切り替わるように。
- ターンごとにカードをドロー
CreateCard()
を利用して、プレイヤーと敵がターンごとにカードを引く処理を追加。
- 敵がカードを出す
- 手札の中から1枚カードを選び、フィールドに出す処理を実装。
EnemyTurn()
内でSetCardTransform()
を呼び出し、カードの移動を管理。

ここまでの実装で、基本的なカードゲームの仕組みが整いました!
このシリーズを通して、Unityでのカードゲーム開発の基礎をしっかり学べます。
ぜひ次回もチェックして、ゲームを完成させましょう!🔥
よくある質問(FAQ)
- Q敵のカードをランダムに出したい場合は?
- A
Random.Range(0, cardList.Length);
を使って、ランダムにカードを選択できます。
- Qターンごとにドローするカードをランダムにしたい
- A
CreateCard
のcard.Init(1);
をcard.Init(Random.Range(1, 4));
のように変更すると、ランダムなカードが引けます。
- Q敵が手札を持っていないとどうなる?
- A
if (cardList.Length > 0)
のチェックがあるので、手札が空なら何もしない ようになっています。