対戦カードゲームをunityとc#とphotonで作りたい:チップのグラフィックの実装(14)

Githubソースコード公開&まとめ

今回はチップのグラフィックを実装していきます。まずは、構想段階ではチップを縦に積んである状態を画面下部に作り、そこから、ダブルクリックで、チップが平面化されて、賭けることが出来るようにするというのを考えました。図にすると下記のようなイメージです。最初はフォトショでこんな感じというイメージを固めました。

まず、チップの画像をイラストレーターで簡単に作りました。パスファインダーでチップの周囲の黄色い棒線を1つ作成し、回転ツールを使用してコピーしています。Altキーを押しながら円の中心をクリックし、回転の中心の基点を設定しています。コピーに✔を入れてコピーした後にCtrl+Dで繰り返しを3回行う事で重複した動作のショートカットを行いました。真ん中の円は外側の円を拡大縮小しています、その際にCtrl+Shiftで縦横の比率を保ったまま変形しています。

それから横から見た図も作成します。これは横に積んだ状態を示す絵に使います。両方ともPNGで書き出して背景が透明になるようにします。

次にアセットフォルダにできたファイルをドラッグ&ドロップします。それをさらにシーンビューにドラッグ&ドロップしてから、Prefab化します。大きさはインスペクター上のtransformのscaleでいじって丁度良い大きさにしています。

2種類のポーカーチップを作成し、画面に実際にドラッグ&ドロップしてみるとこんな感じになりました。

これから、ポーカーチップを積んだ状態の表示方法をスクリプト化していきたいと思います。持ち金がいくらかに関わらず、正しい量のポーカーチップが画面に出るスクリプトを考えます。例えば、黒のチップが100点で紫のチップが500点だとすると、10枚ずつ積むと仮定して、黒のチップのスタックが3本、紫のチップのスタックが2本で、100*10*3+500*10*2=13000点を表示できるとバランスが良さそうです。両替の手間を省くために、常に3000点分は黒のチップで用意するという前提で考えます。

よって持ち金が3000点を切った場合は全て黒のチップで、そして、3000点を超えた分で500で割り切れる分は紫のチップで表示したいと思います。

すると、変数として、紫のチップスタックの本数PurpleStuckNumと紫の余りチップの枚数PurpleChipNumが必要となります。同様にBlackStuckNumと、BlackChipNumも必要です。それから右から数えて何本目にそれを表示するかをカウントする関数としてtotalStuckNumという変数も用意し、スタックを描画するたびにインクリメントさせることを考えます。

まず、持ち金moneyが3000点を切ったシチュエーションをスクリプト化します。黒のチップスタックblackStuckNumはmoneyを1000で割った本数になります。余りのチップはblackChipNumの枚数になります。そして、紫のチップは0です。

 if( money -3000 < 0)
            {
                blackStuckNum = money / 1000;
                blackChipNum = (money % 1000) / 100;
                purpleStuckNum = 0;
                purpleChipNum = 0;

持ち金moneyが3000点を超えた場合は、下記の処理になります。3000点分は黒のチップスタックで表示したいので、その分を引いてから5000で割り、紫のチップスタックの本数を計算しています。同様にそのあまりの枚数も計算します。そして、黒のチップスタックの本数は自動的に3にして、残りを100で割った商がblackChipNumになります。

}else if (money / 3000 > 0)
            {
                purpleStuckNum = (money - 3000) / 5000;
                purpleChipNum =  ((money - 3000) % 5000) / 500;
                blackStuckNum = 3;
                blackChipNum = (money - (5000 * purpleStuckNum)-(purpleChipNum*500) - 3000 ) / 100;
            }

後は、その変数を使ってfor文を作り、オフセット幅を必要なだけ取ってあげて、必要な繰り返し回数コピーしてあげます。

            int k;
            int j;
            if(purpleStuckNum > 0)
            {
                for (j = 0; j < purpleStuckNum; j++)
                {
                    float coh = chiphozOffset * j; //水平オフセット幅の計算
                    totalStuckNum++;

                    for (k = 0; k < 10; k++)
                    {
                        float co = chipOffset * k; //縦オフセット幅の計算
                        Vector3 temp = startposition + new Vector3(-coh, co);//tempというオフセットした位置の計算
                        GameObject pokerchip = (GameObject)PhotonNetwork.Instantiate("pokerchip3", temp, Quaternion.identity, 0);
                    }
                }
            }
            if (purpleChipNum > 0)
            {
                for (j = 0; j < 1; j++)
                {
                    float coh = chiphozOffset * totalStuckNum; //水平オフセット幅の計算
                    totalStuckNum++;
                    for (k = 0; k < purpleChipNum; k++)
                    {
                        float co = chipOffset * k; //縦オフセット幅の計算
                        Vector3 temp = startposition + new Vector3(-coh, co);//tempというオフセットした位置の計算
                        GameObject pokerchip = (GameObject)PhotonNetwork.Instantiate("pokerchip3", temp, Quaternion.identity, 0);
                    }
                }
            }
            for (j = 0; j < blackStuckNum; j++)
            {
                float coh = chiphozOffset * totalStuckNum; //水平オフセット幅の計算
                totalStuckNum++;

                for (k = 0; k < 10; k++)
                {
                    float co = chipOffset * k; //縦オフセット幅の計算
                    Vector3 temp = startposition + new Vector3(-coh, co);//tempというオフセットした位置の計算
                    GameObject pokerchip = (GameObject)PhotonNetwork.Instantiate("pokerchip4", temp, Quaternion.identity, 0);
                }
            }
            if (blackChipNum > 0)
            {
                for (j = 0; j < 1; j++)
                {
                    float coh = chiphozOffset * totalStuckNum; //水平オフセット幅の計算
                    totalStuckNum++;
                    for (k = 0; k < blackChipNum; k++)
                    {
                        float co = chipOffset * k; //縦オフセット幅の計算
                        Vector3 temp = startposition + new Vector3(-coh, co);//tempというオフセットした位置の計算
                        GameObject pokerchip = (GameObject)PhotonNetwork.Instantiate("pokerchip4", temp, Quaternion.identity, 0);
                    }
                }
            }

そうすると、money=13000にした場合、下記のように表示されました。

例えば、money=21400にチップが増えたとしても、正しく描画されています。

money=7800の場合、下記のようになります。

3000点を切った場合でも、(2400点)下記のように対応できていることが確認できました。

次に、ポーカースタックをダブルクリックすると、立面のポーカーチップがDestroyされ、2次元の見下げ図がinstatiateされるクリプトを添付します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;//イベントシステム追加を忘れずに

public class ChipCreate : MonoBehaviour, IPointerClickHandler //ここ重要
{

    public int clickNum = 0; //外部参照用のクリック数の宣言
    Vector3 temp;
    Vector3 position;

    public void OnPointerClick(PointerEventData eventData)
    {
        if (eventData.clickCount > 1)
        {
            Debug.Log(eventData.clickCount);
            temp = this.transform.position;
            GameObject pokerchip = (GameObject)PhotonNetwork.Instantiate("pokerchip2", temp, Quaternion.identity, 0);
            Destroy(gameObject);
        }
    }
}

上のスクリプトChipCreate.csに加え、Rigidbody2DとBoxcolider2Dをアタッチして、重力の影響を受けるようにします。

一方、下にチップが落ちていくのを止めるために床を作り、同様のコンポーネントをアタッチし、Constraintsに全部チェックを入れて固定します。

これで、ポーカーチップが下に落ちる仕組みが出来上がりました。それから、見下げ図になったポーカーチップをクリックしドラッグできるように、カードにアタッチしてあるマウスのドラッグに反応するスクリプトmouse.cs(手札をドラッグして動かす編参照)と、Rigidbody2DとBoxcolider2Dを追加します。Rigidbody2DはisTriggerにチェックを入れ、gravityscaleを0にして、下に落ちないようにします。

下記のGIFのように、クリックするとポーカーチップが動かせるようになりました。同時にポーカースタックからチップが減ります。画像をクリックするとGIF画像が別ウインドウで動きます。

おすすめの記事