Unityでできるみんなが知りたいカードゲーム作りの基本操作


2019.4.10更新

私はカードゲームをUnityで作り始めて8ヶ月になります。

実は、カードゲームを作る上で必要な操作って結構いっぱいあるんです。

私の数少ない経験の中から、よくカードゲームを作るときに使う操作をまとめました!

この記事では、どうやってどうやってカードゲームを作るの?

ということを、なるべく分かり易く伝えたいと思います!

カード・コンポーネントの作成

まずはカードの見かけを作りましょう。

カードは一枚のPNGファイルにまとめてすべてのデザインを入れておきます。


それをスプライト化してから、切り出して、カードの裏表に割り振ることで、カードができます。

これによって、カードを一枚ずつ作るのではなく、複数の表面を持った、一枚のカードコンポーネントを作成します。

これによって個々のカードを作る必要がなくなり、かつ、カードの番号によって好きな表面を呼び出したりできるようになります。

とても便利なので、ぜひ挑戦してみて下さい。

具体例は下記のリンクに詳しいやり方が書いてあります。

トランプカードの表示方法

上で説明した通り、カードの表はいろいろな種類がたくさん混在している状態になります。

トランプでしたら52種類の表面があるということになりますよね。

それを配列(数字の順番)で扱って、好きなものが表示されるようにします。

これにはC#スクリプトを使って好きな面が出せるようにしてあげる必要があります。

最初はカードの表面に付けられているIndex(番号)順にカードを表示する練習を行います。

詳しくはこちらの記事に書いてありますので、ご参考まで。

カードのアニメーション

次に、好きな面を出せるようになったら、カードをひっくり返すアニメーションを付けてあげます。

AnimationCurveという機能を使うと、うまくいくとぺらっとめくれる感じが出せます。

コルーチンという少し難しいコンセプトが出てきます。

私もまだきちんと理解できていないのですが、一定時間処理を待たせたりというようなことができるようです。

ちょっとゲームっぽくなってきましたよね!

やり方は下記のリンクを参考にしてみてくださいね。

カードのシャッフルのやり方

アニメーションができたらカードをシャッフルしてみましょう。

これはカード自体をシャッフルするのではなくて、表面を表示するスクリプトの中の配列(数字の順番)に入っている数字をシャッフルします。

なので、カード自体を物理的にシャッフルするわけではないのです。

よって配列のシャッフルを行っただけではカードは表示されませんので、表示には別途スクリプトを書いてあげる必要があります。

このシャッフルの方法はチュートリアルがべらぼうに分かり易いので、リンク先のチュートリアルは必見です!

チュートリアルは下記の記事のリンクよりどうぞ。

シャッフルしたカードの表示方法

カードの数字の順番をシャッフル出来たらその数字に対応するカードの表面を表示してあげます。

するとずらずらっとシャッフルされたカードを並べることができます。

これで、トランプなどのカードゲームで絶対に使うカードシャッフルのやり方がわかります。

カードの配り方

次はカードを配るというコンセプトを考えます。

カードをプレイヤーに配る場合には、プレイヤーがオンラインで対戦しているという前提をクリアする必要があります。

そこで、まずはPhotonの導入をしましょう。

Photonについてはこちらの特集記事にとっても詳しく書いてあるので興味があれば目を通してくださいね。

ここでは簡単なさわりだけをご紹介します。

カードを一枚配る

オンライン対戦の準備ができたら、まずは、カードを一枚だけ配ってみます。

これはFPSゲーム(銃を構えて撃つゲーム)のプレイヤーの初期配置を利用したものです。

カードをprefab化して PhotonNetwork.Instantiate を使いますが、詳細はこちらの特集記事にとっても詳しく書いてあるの で参考にしてみてください。

簡単に言うと予め作ったカードをネットワーク上に呼び出してあげるというようなことになります。

実例は下記のリンクを参考にしてみてください。

カードを同じデッキから13枚づつ配る

次に手札を13枚ずつ2人のプレイヤーに配ります。

この時、同じデッキから13ずつ配るので、最初に13枚配ったということを、記録しておかないといけません。

そして、13枚を取り除いた、残りの39枚の中から13枚を配るということになります。

これは、初めの13枚を配ったという情報をルーム(部屋)にCustomRoomPropertyを使用して記憶して、ダブりを防ぐような仕組みにしています。

これは処理的には、結構ややこしいので、少し複雑になりますが、ぜひ理解しておきたい内容ですね。

詳細は下記のリンクを参考にしてみてください。


手札を操作する

手札を配ることができたら、次は手札を並び替えたり動かしたりしてみましょう。

手札をドラッグする

手札を動かすためには手札をマウスでクリックして動かしたいので、マウスクリックを検知する必要がありますね。

それから自分のカードを動かした際に、相手の画面でも自分のカードが動くように同期をとる必要があります。

同期についてはPhotonの記事に詳細が書いてあります。

それに加え、自分のカードは自分のみ触れるようにしてあげる必要があります。これはis.Mineというbool値を用いて判断するということになります。

やり方の詳細は、下記のリンクをご参考下さい。

手札を対戦相手に公開する

それから、デフォルトではカードの裏面が対戦相手に表示されていますが、カードを表示して相手に公開したい時もあるでしょう。

そんな時にダブルクリックでカードを公開することを考えました。

ダブルクリックでカードを公開するにはまず、ダブルクリック自体を検知する必要があります。

そして、次にダブルクリックした時に表面を表示するようにスクリプトを書きます。

それに加え、対戦相手に公開しないといけないので、ダブルクリックしたカードのデータを対戦相手側に送らなければなりません

これは同期の取り方の一種になるので、Photonを使ったデータの送受信を行います。

そのやり方は下記の記事を参考にしてみてください。



カードをマウスオーバーでひっくり返す

ゲームによっては裏面のカードをひっくり返して一時的に表面にしたい時もあると思います。

スタッドポーカーの裏面のカードのようなイメージです。

そのために、マウスオーバーでカードをひっくり返すという機能を作ってみました。

これは、 OnPointerEnter(PointerEventData eventData) を使用します。マウスが、オブジェクトに当たった時にトリガーされるということです。

これで簡単に自分の手を確認することができます。

手札情報の取得

次は、手札の情報を取得する方法について考えてみましょう。

これは主に役の判定等で使います。

私の場合は、衝突判定を使って 手札の情報を取得しています。とっても原始的な情報の取得の仕方です。

本来であれば、範囲を指定して、FindGameObjectsWithTagなどを使っても良いと思います。

情報を取得したらそれをCustomRoomPropertyに送ることでルーム(部屋)固有の値として、他のプレイヤーと比較したりできます。

ポーカーの手役判定

参考までに、ポーカーの手役判定を書いたのでもし興味があればどうぞ。

これは、ポーカーの手役判定のための有名な式がありまして、それを流用して書いたものです。

上の図のようにペアのダブり方によってダブった回数が固有の値を取ることを利用して、ペアの判定を行っています。

その他、ストレートやフラッシュなどの手役も計算式を用いて判定しています。

純粋にC#スクリプトによってのみ手役を判定しているので、少し退屈かもしれませんが、スクリプトに慣れてきたらチェックしてみて下さいね。

ポーカーの勝敗判定

それから、取得した手役の情報をもとに勝敗判定をするやり方についても記事を書いています。

いままで、各手役ごとに点数化し、手役が上がるごとに桁数を上げるという効率の悪いやり方をしていました。

この記事に差し掛かる所で、桁数を上げずに、役固有の値を作ることができるということに気づきました。

お互いのプレイヤーの手役の点数をカスタムルームプロパティに送受信し、比べることで勝敗判定を可能としています。

もしよろしければ参考にして下さい。

チップの使い方

トランプゲームにつきものなのがチップですね。ポーカーチップはポーカーをやる上で欠かせません。

ここではチップをどのようにゲームに取り入れたかについて書こうと思います。

チップのグラフィック

ここでは、チップのグラフィックについて考えてみました!

まず、チップを縦に積んである状態を画面下部に作り、そこから、ダブルクリックで、チップが平面化されて、賭けることが出来るようにするというシステムを考えています。

黒のチップが100点で紫のチップが500点です。

10枚ずつ積んで、黒のチップのスタックが3本、紫のチップのスタックが2本で、100*10*3+500*10*2=13000点を表示できるようにしています。

縦に積んであるチップには 重力を掛けていて、下の方からチップを取ると、チップが下に落ちる様子が見えるようにしています。

チップの枚数と点数をきちんとリンクさせているので、良かったら下の記事からやり方を見てみて下さいね。

対戦相手のチップを触れないようにする

対戦相手のチップを触れてしまうと問題がいろいろありますね。自分のチップのみ触れるようにここでは工夫しています。

そのためには、PhotonのIsMine.というbool値を使用しています。

これがTrueの時のみ自分が触れるようにスクリプトを書き換えています

このIsMine.はとても便利なので、色々なところで使われるようです。

実例は下記のリンクからご覧ください。

チップの同期とカウント

チップの同期をとって、チップのグラフィックの枚数と、表示されている点数の値をそろえてあげる必要があります。

チップをの同期をとるためにはCustomRoomPropertyを使用してその都度部屋にある自分のチップをFind.GameObejcts.With.Tagで取得してカウントしています。

そして、その値をTextで表示しています。

お互いのチップを常に監視し続けないといけないので、CustomRoomPropertyが更新されたときに呼ばれるコールバックメソッドである、 OnPhotonCustomRoomPropertiesChangedを利用して、同期をとっています。

詳しくは下記リンクをご覧ください。



チップのアニメーション

ここでは、上のGifのように、プレイヤーがフォールドした場合、フォールドした逆のプレイヤーの方にチップが吸い寄せられ、チップスタックが増えるという動きを考えました。

まず、チップに加速度を与えてあげ、チップを特定の方向に動かしたのち、衝突判定を用いて、チップをデストロイします。

それと同時にチップの情報をtagを用いて取得して、それを計算のカウントに入れてあげています。

最後にPhotonNetwork.Instantiateを使用して縦のスタックにチップを戻してあげています。

詳細は下記リンクからご覧ください。

Githubソースコード・素材

ソースコードと素材は下記リンクからどうぞ!

是非ビルドしたり、流用したりしてみて下さいね。

■横須賀ポーカーver.0.2 GITHUB ソースコード

テストプレイ動画

友人とプレイしている動画をYOUTUBEにアップしてみました!

どんな感じのゲームになっているか、是非ご覧ください。


まとめ

これで、私の使っているカードゲームに必要な基本的な操作は、大体網羅できたと思います!

少しでも、何かのお役に立てばうれしく思います。

是非、これを機会にカードゲーム、ボードゲームを一緒に作りましょう!

まとめに戻る↓

スポンサーリンク
おすすめの記事