気ままなUnityエンジニアブログ

新米Unityエンジニアが送る解説アウトプットブログです。Twitter : @UjinUnity

MENU

【Unity ゲーム制作】神経衰弱ゲームを作ろう!〜その8 ( カードの裏返し処理を作ろう!)

スポンサーリンク

前回は同じカードを選択したときの処理を実装しました!

今回は「同じカードを選択したらそのカードを非表示にする」処理と
異なったカードを選択したら、選択したカードを背面表示に戻す処理の両方を実装していきましょう!

「Card.prefab」に「CanvasGroup」を導入しよう!

まずは、「カードを非表示」にするために、とあるコンポーネントを導入します。

CanvasGroupについては、公式サイトを参照してください
UnityEngine.CanvasGroup - Unity スクリプトリファレンス


簡単に説明すると、Canvas内部で使用するコンポーネントであり、導入したオブジェクトのアルファ値などを変更したいときに使用します!。

では、早速導入していきましょう。

Card.prefabを開き、Inspector から AddComponentを選択 → CanvasGroup を検索して導入してください。

f:id:Wojtek:20190928181859p:plain


するとこのような画面が出ると思います。
このAlphaによってオブジェクトのアルファ値を変更することができるようになります。


f:id:Wojtek:20190928181921p:plain


コンポーネントが導入できたら、 Card.csに CanvasGroup の変数を作成し、そこにアタッチしましょう!

public class Card : MonoBehaviour {

    // カードのID
    public int Id;

    // 表示するカードの画像
    public Image CardImage;

    // 透過処理用
    public CanvasGroup CanGroup;

    // 選択されているか判定
    private bool mIsSelected = false;

    // カード情報
    private CardData mData;

f:id:Wojtek:20190928181937p:plain


アタッチできたら、Card.csに処理を追加していきます。


 public void Set (CardData data) {

        // カード情報を設定
        this.mData = data;

        // IDを設定する
        this.Id = data.Id;

        // 表示する画像を設定する
        // 初回は全て裏面表示とする
        this.CardImage.sprite = Resources.Load<Sprite> ("Image/card_back");

        // 選択判定フラグを初期化する
        this.mIsSelected = false;

        // アルファ値を1に設定
        this.CanGroup.alpha = 1;

    }

OnClick()で選択した場合、Cardオブジェクトは表示されている状態になります。

次に、「選択したカードが異なったカード同士」だった場合の処理と
「同じだった場合」の処理を記述します。

それぞれの役割を整理すると

  • 「選択したカードは同じではない」 : 「カードを背面表記に戻す」
  • 「選択したカードが同じ」     : 「カードを非表示にする」


それぞれの役割を実行する関数を作成しましょう!

    ///  <summary>
    /// カードを背面表記にする
    /// </summary>
    public void SetHide () {

        // 選択判定フラグを初期化する
        this.mIsSelected = false;

        // カードを背面表示にする
        this.CardImage.sprite = Resources.Load<Sprite> ("Image/card_back");
    }

    /// <summary>
    /// カードを非表示にする
    /// </summary>
    public void SetInvisible () {

        // 選択済設定にする
        this.mIsSelected = true;

        // アルファ値を0に設定 (非表示)
        this.CanGroup.alpha = 0;

    }

SetHide 関数では、「カードを背面状態に戻し、選択可能状態にする」処理を記述しています。

SetInvisible 関数では、「選択済み状態にし、カードのアルファ値を 0 (非表示)にする」処理を行います。

先ほど導入した「CanvasGroup」のアルファ値を変更することで、カードを見えない状態にしております。


次に、CardCreateManager.csの内容も修正していきましょう。

CardCreateManager.csの処理を変更しよう!

まずはCardCreateManager.csに「生成したCardオブジェクトを保管する変数」を作成しましょう!

public class CardCreateManager : MonoBehaviour {

    // 生成するCardオブジェクト
    public Card CardPrefab;

    // 「カード」を生成する親オブジェクト
    public RectTransform CardCreateParent;

    // 生成したカードオブジェクトを保存する
    public List<Card> CardList = new List<Card> ();

そして、生成したCardオブジェクトを CardList に保管します。


        // リストの中身をランダムに再配置する
        List<CardData> randomCardDataList = SumCardDataList.OrderBy (a => Guid.NewGuid ()).ToList ();

        // カードオブジェクトを生成する
        foreach (var _cardData in randomCardDataList) {

            // Instantiate で Cardオブジェクトを生成
            Card card = Instantiate<Card> (this.CardPrefab, this.CardCreateParent);
            // データを設定する
            card.Set (_cardData);

            // 生成しかカードオブジェクトを保存する
            this.CardList.Add (card);
        }

これで生成したCardオブジェクトを変更することができるようになりました。

現在は、Start() にて一回だけカードを生成する処理が記述されておりますが、新たに関数を追加していきましょう。

追加する関数は

  • カードを生成する専用の関数
  • カードを背面、非表示にする関数

を作成していきます。

  /// <summary>
    /// カードを生成する
    /// </summary>
    public void CreateCard () {

    }

    /// <summary>
    /// 取得していないカードを背面にする
    /// </summary>
    public void HideCardList () {

    }

CreateCard()関数には、現在 Start()に記述している生成処理をそのままコピペしてください。

HideCardList() 関数では、「生成したCardオブジェクト」に処理を実行していきます。

    /// <summary>
    /// 取得していないカードを背面にする
    /// </summary>
    public void HideCardList (List<int> containCardIdList) {

        foreach (var _card in this.CardList) {

            // 既に獲得したカードIDの場合、非表示にする
            if (containCardIdList.Contains (_card.Id)) {

                // カードを非表示にする
                _card.SetInvisible ();
            }
            // 獲得していないカードは裏面表示にする
            else {

                // カードを裏面表示にする
                _card.SetHide ();
            }
        }
    }

HideCardListでは、生成したカードをforeachで呼び出し、「取得したカードと同じID」だった場合は、そのカードを非表示に、
違う場合はカードを背面表示にする 処理を記述しています。


それでは、その処理をGameSceneManagerに記述しましょう。

public class GameSceneManager : MonoBehaviour {

    // 一致したカードIDリスト
    private List<int> mContainCardIdList = new List<int> ();

    // カード生成マネージャクラス
    public CardCreateManager CardCreate;

    void Start () {

        // 一致したカードIDリストを初期化
        this.mContainCardIdList.Clear ();

        // カードリストを生成する
        this.CardCreate.CreateCard ();
    }

void Update () {

        // 選択したカードが2枚以上になったら
        if (GameStateController.Instance.SelectedCardIdList.Count >= 2) {

            // 最初に選択したCardIDを取得する
            int selectedId = GameStateController.Instance.SelectedCardIdList[0];

            // 2枚目にあったカードと一緒だったら
            if (selectedId == GameStateController.Instance.SelectedCardIdList[1]) {

                Debug.Log ($"Contains! {selectedId}");
                // 一致したカードIDを保存する
                this.mContainCardIdList.Add (selectedId);
            }

            // カードの表示切り替えを行う
            this.CardCreate.HideCardList (this.mContainCardIdList);

            // 選択したカードリストを初期化する
            GameStateController.Instance.SelectedCardIdList.Clear ();
        }
    }


まずはプロパティに 「CardCreateManager」の変数を追加し、Hierarchyにあるオブジェクトにアタッチしてください。

その後、CardCreateManager.CreateCard()関数を実行し、カードの生成を行なっております。

そして、前回記述した、「同じカードを選択していたら〜」の処理に先ほど作成した「HideCardList」関数を呼ぶように記述します。

ここまでできたらGameを起動してみましょう!

f:id:Wojtek:20190928182811g:plain


上記のように動作していたら成功です!

しかし、切り替えが雑な状態ですよね。。。
このままでは 不恰好なので「DOTween」を導入して綺麗なアニメーションを実装してみましょう!