Unityカードゲームゲームの作り方メモ

【Unity 2D】シャドウバース風カードゲームの作り方!ターン制&ドロー機能を実装(パート4)

Unity

はじめに

こんにちは!今回も シャドウバース風の2Dカードゲーム を作っていきます。前回のパート3では、以下の機能を実装しましたね。

  • カードを手札に生成 する
  • ドラッグ&ドロップでフィールドに移動 できるようにする
  • 両プレイヤーに3枚ずつカードを配る

これで、ゲームの基本的なカード配置ができるようになりました。しかし、まだカードを出した後の動きがありませんよね。

そこで今回の パート4 では、ゲームに「ターン制」を実装していきます!

今回の実装内容

  1. ターンの切り替え
    • プレイヤーと敵のターンを交互に切り替える
    • ターンエンドボタン を押すと次のターンへ進む
  2. ドロー機能の追加
    • ターン開始時にカードを1枚ドロー する
  3. 敵の行動を実装
    • 敵のターンになったらカードを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. ターンの切り替え処理の解説

上記のスクリプトでは、ターン制をシンプルに実装しています。

isPlayerTurn
true のときプレイヤーのターン、false のとき敵のターンになります。

Start() メソッド
ゲーム開始時に StartGame() を実行し、最初に isPlayerTurntrue に設定。続いて TurnCalc() を呼び出し、最初のターンを開始します。

TurnCalc() メソッド
現在のターンを判定し、プレイヤーのターンなら PlayerTurn()、敵のターンなら EnemyTurn() を実行します。

ChangeTurn() メソッド
isPlayerTurn の値を反転させて (true → falsefalse → true) ターンを切り替え、TurnCalc() を再実行します。


1-3. ターンエンドボタンの設定

次に、プレイヤーがターンを終了できるように、ボタンを設定 します。

  1. Canvas内に「Button」を作成
    • GameObjectUIButton を選択し、名前を TurnEndButton に変更
    • Textターンエンド に変更
  2. ボタンの OnClickGameManagerChangeTurn() を設定
    • TurnEndButtonInspector を開く
    • 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上での設定

  1. GameManager を空のオブジェクトにアタッチ
  2. Inspectorで PlayerHandTransformEnemyHandTransform を設定
  3. ターンエンドボタンに ChangeTurn() を設定

② 実行テスト

  1. ゲームを開始すると、プレイヤーのターンが開始
  2. ターンエンドボタンを押すと、敵のターンに切り替わる
  3. ターン開始時に、それぞれの手札に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();
}

この処理では、以下の動作を行います。

  1. 敵の手札(EnemyHandTransform)にあるカードを取得
  2. 手札にカードがあれば、一番最初のカードを選択
  3. そのカードを敵のフィールド(EnemyFieldTransform)に移動
  4. 「敵がカードをフィールドに出しました」とログを出力
  5. ターンを終了



3-4. スクリプトを適用する

ここまで作成したスクリプトを適用するために、GameManagerのInspectorで設定を確認 しましょう。

GameManagerの設定

  • EnemyHandTransform → 敵の手札エリアの Transform を設定
  • EnemyFieldTransform → 敵のフィールドエリアの Transform を設定

カードPrefabの設定

  • CardController に CardMovement が正しくアタッチされていることを確認
  • CardMovementの defaultParent が正しく更新されることを確認

3-5. ゲームを実行して確認

  1. ゲームを開始するとプレイヤーのターンが開始
  2. ターンエンドボタンを押すと敵のターンへ
  3. 敵の手札にカードがあれば、1枚フィールドに移動
  4. 敵のターンが終了し、プレイヤーのターンに戻る

これで、敵がターンごとに1枚カードを出すシンプルなAI が完成しました!


3-6. 敵の動きを強化するには?

現在の敵のAIは 「手札の最初のカードを1枚出すだけ」 というシンプルなものですが、以下の方法でさらに進化させることができます。

ランダムなカードを選んで出す

int index = Random.Range(0, cardList.Length);
CardController card = cardList[index];

敵が手札の中からランダムにカードを選ぶようになります。

特定の条件を満たしたときにカードを出す

  • コスト管理を追加し、出せるカードがあるか判定
  • プレイヤーのカード状況に応じて行動を変える
  • カードの種類(攻撃系・防御系)に応じた選択をする

複数枚のカードを出す

  • 1ターンに 2枚以上のカードを出せるようにする
  • for ループを使って、複数のカードをプレイ可能



まとめ

これで、シャドウバース風の2Dカードゲームのターン制を実装 することができました!
今回のパートでは、以下の3つの機能を追加しました。

ターンの切り替え処理
ターンごとにカードをドローする処理
敵がカードをフィールドに出すシンプルなAI

学んだポイント

  1. ボタンを使ってターンを切り替える
    • isPlayerTurn を使ってプレイヤーと敵のターンを管理。
    • ChangeTurn() を呼び出すことで、ターンが切り替わるように。
  2. ターンごとにカードをドロー
    • CreateCard() を利用して、プレイヤーと敵がターンごとにカードを引く処理を追加。
  3. 敵がカードを出す
    • 手札の中から1枚カードを選び、フィールドに出す処理を実装
    • EnemyTurn() 内で SetCardTransform() を呼び出し、カードの移動を管理。

ここまでの実装で、基本的なカードゲームの仕組みが整いました!
このシリーズを通して、Unityでのカードゲーム開発の基礎をしっかり学べます
ぜひ次回もチェックして、ゲームを完成させましょう!🔥




よくある質問(FAQ)

Q
敵のカードをランダムに出したい場合は?
A

Random.Range(0, cardList.Length); を使って、ランダムにカードを選択できます。

Q
ターンごとにドローするカードをランダムにしたい
A

CreateCardcard.Init(1);card.Init(Random.Range(1, 4)); のように変更すると、ランダムなカードが引けます。

Q
敵が手札を持っていないとどうなる?
A

if (cardList.Length > 0) のチェックがあるので、手札が空なら何もしない ようになっています。

タイトルとURLをコピーしました