ブラックジャックの作り方5 Hit・Stand処理と絵札の効果を作る

Unity カードゲームの作り方


Unityの本格ゲーム制作講座はこちら
【30日間の全額返金保証付き】

前回の記事でブラックジャックの大まかな流れを作成することができました。

前回の記事:

ブラックジャックの作り方4 ゲームシステムとbet(賭け金)システムを作る
前回の記事でカードを配れるようになりました! 前回の記事: 今回の記事では実際にブラックジャックのゲームの流れを作っていきましょう! 賭け金を決めてベットする処理やコルーチンを用いたゲームの管理システムを構築していきます。 ブラ...

今回はHit、Stand処理を作り、カードを引くか引かないかの分岐や、ジャック、クイーン、キングを10扱いにしたり、エースを11or1で選択できるようにしていきます。

ここまで作り終えたら、ブラックジャックは完成です!


【Unity入門の森の最新ゲーム開発講座もお届け】

ゲームの結果をポイントに反映させてみよう!

前回の記事ではベットを決定し、カードを配り、プレイヤーの行動の分岐&実行処理まで作りました。

あとはプレイヤーの行動に合わせてカードの数字を足し21を超えたかどうかを判定すればゲームの流れは完成します。

それでは実際にプレイヤーが引いたカードの数値を足してみて21を超えたかどうか判定してみましょう!

ヒットを作る

プレイヤーの行動にはヒットとスタンドの2種類ありますが、まずヒットの方を作ってみましょう!

前回の記事でプレイヤーの行動はSceneManagerのAction列挙型で定義しています。

また、GameLoopメソッドの中でプレイヤーの行動に合わせた処理を行なっています。

ヒットの処理を実装する場所はその中のAction.Hitの部分になります。

新しくSceneManagerコンポーネントに追加するCheckPlayerCardsメソッドはプレイヤーが引いたカードの数字を足し合わせて21を超えたかどうかを判定するメソッドになります。

そのメソッドがfalseを返した場合はヒットを選択した場合でもループから抜けるようにします。

また、現在のゲームに勝ったか負けたかを表すdoWin変数も追加しています。

プレイヤーの行動用のループを抜けたあとにポイント計算を行なっているので、doWin変数はそちらで使用します。

上のサンプルコードでのTransform.GetComponentsInChildrenメソッドは子GameObjectにアタッチされているコンポーネント全てを取得するメソッドなので覚えておくと便利でしょう。

ヒットを選択した際にプレイヤーカードの数の合計が21を超えた場合、ポイントがベットの分減るようになっているので確認してみましょう!

実行したところ、少しわかりづらいのでゲームの結果を判定した後にその結果を画面に表示させてみましょう!

シーンの「Canvas」にUI > Textをクリックしテキストを追加してください。名前は「ResultText」にしてください。

「ResultText」はゲームの結果がわかるように大きなものにしてください。 

追加したら、次のコードをSceneManagerコンポーネントに追加してください。

問題なければ結果に応じてテキストが画面に表示されるようになっています。

スタンドを作る

次にプレイヤーの行動のスタンドを作りましょう!

こちらもヒットと同じくGameLoopメソッドの中でプレイヤーの行動の処理を行なっている部分のAction.Standの部分に処理を追加します。

スタンドの処理はStandActionメソッドの中で行なっています。

StandActionメソッドはプレイヤーが勝つとtrueを返し、負けるとfalseを返すようになっています。

実装できたら再生して動作を確認しましょう!

J、Q、Kを10として扱うようにしよう!

実際のブラックジャックではJack、Queen、Kingは数字の10として扱いますが、まだその処理を作っていないので引いたカードによっては最初から21を超えてしまう場合もあります。

そのようなケースにはサンプルコードでは対応していないので、次はその部分の対応をしてみましょう!

CardコンポーネントにUseNumberプロパティを追加してください。

UseNumberプロパティはNumberフィールドの値を見てブラックジャックで使う数字に変換するものになります。

追加できたら、SceneManagerコンポーネントの中からカードの合計を計算している部分のCardコンポーネントのNumberフィールドの部分をUseNumberプロパティに変更します。

変更する部分はCheckPlayerメソッドとStandActionメソッドの中になります。

変更できたら再生して動作を確認しましょう!

エースを1か11か選択できるようにしよう!

次にブラックジャックでは数字の1の場合は1か11のどちらか選択できるようになっているのでそちらの対応もしていきましょう!

エースの数値選択の機能実装のためにはCardコンポーネントを拡張する必要があります。

  • Bool型のIsLargeフィールドを追加する
  • UseNumberプロパティを拡張し数字の1の場合はIsLargeフィールドに合わせて返す値を1または11で切り替えるようにする

また、エースの場合のみ数字の1か11どちらを選択したかわかるように「Card」プレハブの右下あたりにテキストを追加します。

「Card」プレハブに追加するGameObject

  • テキストを追加し、名前を「OptionalNumberText」にする。
  • 右下に配置する。
  • 見た目を整える。

追加した「OptionalNumberText」は、CardコンポーネントのSetCardメソッドの中で制御します。

上のコードを書いてCardコンポーネントへのエースカードの数値変換処理はできました。

IPointerClickHandlerインターフェースについて

あとはどちらの数字にするか選択できるようにするだけです。

ここは簡単にエースのカードをクリックすると1か11かで切り替わるようにしましょう!

注意点としてUnity UIのコンポーネントではOnMouseAsButtonメソッドでのクリック操作は基本的にできません。

代わりにUnity UIではUnityEngine.EventSystems.IPointerClickHandlerインターフェースをコンポーネントに継承することでどのGameObjectでもクリック操作に対応することができます。

UnityEngine.EventSystems.IPointerClickHandlerインターフェースを継承した場合はOnPointerClick(PointerEventData eventData)メソッドを実装する必要があります。

このサンプルコードを追加すれば、カードがAの時にクリックすると先ほど追加したテキストが1か11かで切り替わるようになります。

ちなみにUnityEngine.EventSystems.IPointerClickHandlerには他にもいくつかの種類があります。これらのインターフェースを継承することでクリック以外の操作にも対応することができます。

下にあげたインターフェイスは全てUnityEngine.EventSystemsの中にあります。

  • IPointerEnterHandler:マウスカーソルなどのポインターが上に来た時のイベント
  • IPointerExitHandler:マウスカーソルなどのポインターが上から外れた時のイベント
  • IPointerDownHandler:マウスカーソルなどのポインターを押した時のイベント
  • IPointerUpHandler:マウスカーソルなどのポインターを話した時のイベント
  • IPointerClickHandler:マウスカーソルなどのポインターでクリックした時のイベント
  • IBeginDragHandler:マウスカーソルなどのポインターでドラックし始めた時のイベント
  • IDragHandler:マウスカーソルなどのポインターでドラックしている時のイベント
  • IEndDragHandler:マウスカーソルなどのポインターでドラックし終えた時のイベント
  • IDropHandler:マウスカーソルなどのポインターでドラック中にドロップ操作をした時のイベント

ちなみにこれらのインターフェースはシーン上にEventSystemコンポーネント及びInputModuleコンポーネントがないと作動しません。

これらのコンポーネントはメニューのGameObject > UI > Event Systemで作成できるGameObjectにアタッチされているので上記インターフェースを利用したい場合は忘れずシーンに配置しておくようにしましょう。

ディーラーのエースは11にする

トランプのカードのエースを1か11かで選択できるようになりました。

ディーラーにもエースが配られる場合もあるのでその場合は必ず11になるようにSceneManagerコンポーネントを修正していきます。

追加できたら、ディーラーのエースは必ず11になるはずです。

ちなみにディーラーのエースをクリックすると数値も切り替わってしまいますが、裏技的な感じがするのであえてここではそのままにしておきます。

そのような処理を防ぎたい場合はCardコンポーネントのOnPointerClickメソッドでディーラーのカードの時だけクリックできないようにする必要がありますので腕に自信がある人は作ってみるのもいいでしょう。

ゲームオーバーとクリア処理を追加する。

最後にゲームポイントを見て0以下になったらゲームオーバー、目標ポイントを上回ったらゲームクリアになるようにしましょう!

変更する部分はSceneManagerコンポーネントのGameLoopメソッドのwhilte文の最後になります。

上のスクリプトを追加したら、シーンに目標ポイントを表示するためのGameObjectを追加しましょう!

追加する場所は「UI」の子GameObjectがいいでしょう。

「UI」の子GameObjectである「Point」を複製して「GoalPoint」と名付けましょう。

「GoalPoint」の子GameObjectには次の操作を行ってください。

  • 「Label」のテキストを「目標ポイント」に変更する
  • 「PointText」の名前を「GoalPointText」に変更する

ここまでできたらSceneManagerコンポーネントのGoalPointTextに「GoalPoints」を必ずアタッチしてください。

この状態で再生するとポイントによってゲームオーバーになったり、クリアになったりするはずです。目標ポイントは適宜調整してください。

ここまででついにブラックジャック完成です!

まとめ

今回の記事でブラックジャックを完成させることができました!

実際にゲームを作る際はブロック崩しやシューティングゲームなどより、ブラックジャックのようなカードゲームの方がUIやゲームの流れがきっちりしているので手間がかかりやすくなります。

今回のブラックジャックの作り方講座ではゲームに必要な要素を最小限作っているだけですが、それでも結構な分量になります。

腕に自信がある方は本講座で作ったものを見栄えよくしたり、より遊びやすくなるように改造していくといいでしょう!

その際は毎回一から作成するのではなく、既に作ったものを使い回して作業量を少なくするのがおすすめです。

将来の拡張性のことを考えて、プレハブの内容やコンポーネントの内容をシンプルに保てるといいですね。

今回の記事ではコンポーネントのメソッド単位が長いものもいくつか出てきましたが、そのようなメソッドもよく見ると分割してもいい部分やちょっと工夫すると他の部分でも使いまわせそうな処理があります。

同じ処理が出てきてる部分を上手にまとめることができると利用しやすいコンポーネントやクラスなどになっていくので、そのあたりも今後意識しながら作っていきましょう!

例として挙げると、SceneManagerコンポーネントのDealCardsメソッドの次の部分を見てみましょう!

シーンに配られたカードを削除している処理ですが、次のように子GameObjectを削除するメソッドを新しく追加し、それを使うようにするとわかりやすくなります。

今回例に挙げたものでは拡張メソッドとして定義するとSceneManager以外でも使えるようになるので、より便利になると思います。

今回の記事をまとめると次のようになります。

  • コンポーネントにUnityEngine.EventSystem.IPointerClickHandlerを継承するとクリックした時の処理を追加できる。
  • 似たような処理を上手にまとめるとコンポーネントを作りやすくなるのでどんどんまとめるのがおすすめ!

次からはまた別のゲームを作っていきましょう!

Unityカードゲーム開発講座へ戻る>>

参考用:スクリプトの完成図

ちなみに今回の記事で作成したスクリプトの完成図は次のようになります。

Unityカードゲーム開発講座へ戻る>>


【Unity入門の森の最新ゲーム開発講座もお届け】

コメント

  1. Anonymous より:

    完成しました!!いつも丁寧で応用の効く解説ほんとうに助かります!!

    • ばこ@Unity入門の森 より:

      完成おめでとうございます!
      そしてコメントありがとうございます^^
      これからも役立つ講座作り続けます!

  2. kei より:

    全5回、拝読させていただきました。
    ここまでやったのですが何故かベッドを入力→カードを引くという処理が実行されません。スクリプトを穴があくほど見直したのですがこちらでは皆目検討もつきませんでした。ありがちなミスなどがあればご教授お願いします。

    • ばこ@Unity入門の森 より:

      講座読んでいただきありがとうございます!
      最後までできた人が何人もおられるので恐らくどこかでミスがあるのかなと思います。
      アタッチのところで何か忘れてるものがあるとかかがUnityだとありがちですね。
      古典的ではありますが、ボタンを引くという動作の前後にDebug.Log(“ここまで動いてるよ”);などを入れて動作がどこまで走ってるかを確認するなどしてみると良いかなと思います。

      • Kei より:

        コメントが遅れました。無事に動くようになりました!どうやら原因はOKButtonのOnClick()でFalseにしていなかったのとEditor And Runtimeに設定してないことだったようです。
        ともかく分かりやすい講座をありがとうございました!

        • ばこ@Unity入門の森 より:

          おー!無事に完成できたようで何よりです!
          わざわざ報告コメントしていただきありがとうございました!

          最後まで読んでいただけてうれしいです^^

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