【第15日目】UnityとPUN2とC#でカード別のコストと効果を使用する

こんにちは、今日はカード別のコストと効果を発生させたいと思います。

現状3種類のカードがありますが、カードに書いてある番号がカードのコストとして、マナトークンをその数だけ消費し、

カード別の効果を呼んであげるようにしたいと思います。

カード別のコストと効果クラスの作成

現在は、cardIndexによって同じカードPrefabのマテリアルを切り替えてカードの種類を表現しています。

同様にcardIndexの値を引数にして、マナコストや、効果を返してあげるメソッドを用意したクラスを作りました。

これが、良いやり方かどうか自信が無いので、取り急ぎこれでやって、もし、変更が必要そうであれば、適宜切り替える事とします。

カードのインデックス値を引数にして値や処理を返すメソッドを作る

 

cardIndexが0,1,2の場合をバラバラにif文で返しています。

これもあまり良いやり方じゃないかもと思いつつ、とりあえず結果動けばいいやという素人根性丸出しでやっています。

CardEffects.csを取り合えず、貼っておきます。

 

これに他クラスからアクセスしていくことにします。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardEffects : MonoBehaviour
{
  
    public int SwitchManaCost(int cardindex)
    {
        if (cardindex == 0)
        {
            return 1;
        }else if(cardindex == 1)
        {
            return 2;
        }
        else if (cardindex == 2)
        {
            return 3;
        }
        else
        {
            return 4;
        }
    }
    public void CardEffectMethods(int cardindex)
    {
        if (cardindex == 0)
        {
            Debug.Log("effect01");

        }
        else if (cardindex == 1)
        {
            Debug.Log("effect02");
        }
        else if (cardindex == 2)
        {
            Debug.Log("effect03");
        }
        else
        {
            Debug.Log("error effect");
        }
    }
}

 

カードのコストをpublic変数として格納する

同じカードのプレファブにくっついているCardSwitcher.csに追記します。

このスクリプトではマテリアルのスイッチと、その同期をPUN2で行っています。

同様に、manaCostというpublic変数にCardEffects.csにアクセスして得られたマナコストを代入して、同じく同期をしておきます。

 

マナコストの同期は必要かわかりませんが、今後の展開によっては、他プレイヤーのカードのコストが問題になる場合もあり得るので、一応やっておきます。

CardSwitcher.csを参考までに張っておきます。

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;

public class CardSwitcher : MonoBehaviourPunCallbacks, IPunObservable
{
    public int cardIndex;
    public int manaCost;

    [SerializeField] Material[] CardMat;
    public void SwitchMaterial(int x )
    {
        cardIndex = x;
        gameObject.GetComponent<MeshRenderer>().material = CardMat[cardIndex];
    //今回追加部分のcardEffectsにアクセス
        CardEffects cardEffects = GetComponent<CardEffects>();
        manaCost = cardEffects.SwitchManaCost(cardIndex);
    }

    //ここから同期の処理
    void IPunObservable.OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
          if (stream.IsWriting)
        {
            stream.SendNext(cardIndex); //cardIndexの情報を送る
            stream.SendNext(manaCost); //shereManaCostの情報を送る
        }
        else
        {
            cardIndex = (int)stream.ReceiveNext(); //cardIndexの情報を受信
            manaCost = (int)stream.ReceiveNext(); //shereManaCostの情報を受信
            SwitchMaterial(cardIndex);//materialに反映
        } 
    }
    
}

 

カードのコストをpublic変数として格納する

以前は、手札にカードがある時のみ、カードを使えるようにしていたので、HandRemover.csの中で、tagが"Hands"になっている時のみうけつけるOnMouseDragの処理を書いていました。

ところが、このOnMouseDragはドラッグしている間処理を呼び続けるので、カードの使用の際には向いていないという事が判明し、OnMouseDownに書き換えました。

 

これで、ワンクリックにつき、一回しか呼ばれないという事になります。

"Cost"タグが付いているオブジェクトを配列で全取得するcostsという変数と、

自分のトークンだけを格納するmyCostという変数の二種類を使い分けています。

 

自分のトークンの数とマナコストを比べて、マナコストに足りてれば、カードを使う処理を行うようにif文を書いています。

そして、マナコストの数だけ、マナトークンを消費するように処理を書きました。

 

以下が、追記して改変した、HandRemove.csになります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;

public class HandRemover : MonoBehaviour
{
    //自分のマナトークン配列
   
    public GameObject[] myCost;
    public GameObject[] costs;
    void OnMouseDown()
    {
        //手札の時にしかこの処理を行わない
        if (tag == "Hands")
        {

            //配列を空にする
            myCost = new GameObject[0];
            costs = new GameObject[0];

            //"Cost"タグが付いているオブジェクトを配列で全取得
            costs = GameObject.FindGameObjectsWithTag("Cost");

            int j = 0;

            Debug.Log(costs.Length);

            //配列の回数分下記の処理を繰り返す
            for (int i = 0; i < costs.Length; i++)
            {
                //i番目の配列のPhotonViewを取得する
                PhotonView c_PV = costs[i].GetComponent<PhotonView>();

                //i番目の配列のPhotonViewが自分のである場合のみ
                if (c_PV.IsMine)
                {
                    //自分のマナトークン配列にゲームオブジェクトを格納する
                    List<GameObject> list = new List<GameObject>(myCost);
                    list.Add(costs[j]);
                    myCost = list.ToArray();

                    j++;
                }
            }

            CardSwitcher cardSwitcher = GetComponent<CardSwitcher>();
            

            //自分のマナトークン配列がマナコストより長い場合
            if (myCost.Length >= cardSwitcher.manaCost)
            {
                Debug.Log(myCost.Length + "and" + cardSwitcher.manaCost);
                //手札を場札とする処理を呼ぶ
                HandRemove();

                CardEffects cardEffects = GetComponent<CardEffects>();

                cardEffects.CardEffectMethods(cardSwitcher.cardIndex);

                //自分のマナトークン配列から一番目の要素を破壊する
                for(int i = 0; i < cardSwitcher.manaCost; i++)
                {
                    PhotonNetwork.Destroy(myCost[i]);
                }
            }
        }
    } 

    void HandRemove()
    {
        //HandHolderの取得
        GameObject handHolderObject = GameObject.Find("HandHolder");
        HandHolder handHolder = handHolderObject.GetComponent<HandHolder>();

        //CardSwitcherのIndexの取得
        CardSwitcher cardSwitcher = GetComponent<CardSwitcher>();
        var removeNum = cardSwitcher.cardIndex;

        //Indexと同じものをHandHolderの手札配列から一つ削除
        var list = new List<int>();
        list.AddRange(handHolder.hands);
        list.Remove(removeNum);
        handHolder.hands = list.ToArray();

        //手札タグをカードタグに付け替える(場に戻すため)
        tag = "Card";

        //rigidbodyを付け、ひっくり返す、
        Rigidbody rigidbody = gameObject.AddComponent<Rigidbody>();
        rigidbody.transform.rotation = Quaternion.Euler(0, 0, 180);
        rigidbody.transform.position = new Vector3(5.47f, 4.425f, 11.276f);

        //回転を拘束
        rigidbody.constraints = RigidbodyConstraints.FreezeRotation;
    }
}

おわりに

これで、マナコストに見合うマナトークンを消費し、デバッグログに、エフェクトを出す事に成功しました。

このデバッグログの部分をカードの能力に書き換えてあげれば、カードゲームが成立しそうです。

問題はカードの能力が決まってないという話ですね。

 

取り急ぎはライブラリを削るカードとかマナトークンを奪うカードとかを作る感じですかね、、、ゲーム性がまだ煮詰まっていないのです。

これから、おいおい考えていこうと思います。

 

それでは、また!

 

 

おすすめの記事