【Unity】RPGを作るチュートリアルその99 お店のアイテム購入処理を実装

【Unity】RPGを作るチュートリアルその99 お店のアイテム購入処理を実装

シンプルなRPGをUnityで作るチュートリアルシリーズの99回目です。大台までもう少しです(白目)

第98回ではお店に入った時の選択肢を表示する機能を作成しました。イベントからお店を呼び出す機能についても実装しました。

今回はお店でアイテムを買う動作を実装していきます。

 

 

制作環境

MacBook Pro 2023 Apple M2 Max

Unity6 (6000.0.30f1) Silicon

 

作業内容と順序

シンプルなRPGを作る上でどんな作業が必要か、どんな順番で作っていくと良さそうか、別ページで検討しました。基本的にこの流れに沿って進めていきます。

 

チュートリアルの一覧

このシリーズ全体の一覧は以下のページにまとめています。

 

前回の内容

前回はお店に入った時の選択肢を表示する機能を作成しました。イベントからお店を呼び出す機能についても実装しました。

 

お店でアイテムを購入する処理

お店の機能を呼び出して、お店での選択肢を選べるところまで実装しました。今回はその選択肢として「買う」を選んだ際に、品揃えとして指定したアイテムをリストに表示する機能、選択したアイテムを購入する機能を実装していきます。

お店に関するクラスの構成としては、

  • お店全体の管理クラス
    • お店の処理完了を通知するコールバック用インタフェース
    • お店の選択肢用のコールバック用インタフェース
    • お店の選択肢用の制御クラス
    • お店の選択項目を表現するEnum
  • お店のアイテム画面を制御するクラス
    • 購入に関するアイテム制御のクラス
    • 購入処理を行うクラス
    • 売却に関するアイテム制御のクラス
    • 売却処理を行うクラス

のように処理範囲を分けており、今回は主にお店のアイテム画面を制御するクラスと、購入に関するアイテム制御のクラス、購入処理を行うクラスを実装していきます。また、アイテムにカーソルを合わせた際に、装備によるパラメータ変動も画面上に表示したいので、これを管理するクラスも作成します。

メニュー画面のアイテム画面や魔法画面のように、UIの枠は共通して使いつつ、画面に応じて表示する内容を切り替えていく方式で実装したいと思います。

アイテムの購入時は確認メッセージを表示する方式で実装したいと思います。そのため、アイテム選択画面でアイテムを選択後、一度「ShopManager」に処理を戻して、はい、いいえの選択肢を表示するようにします。

 

装備によるパラメータ変動を管理するクラス

アイテムにカーソルを合わせた際に、パラメータがどのように変動するかを画面上に表示するためのクラスを用意します。といっても実際の処理については装備画面で作成したものと同じなので、これを継承してお店用の別クラスとして作成します。処理が同じならクラス自体を使いまわしても良いのですが、将来的にお店用の追加処理を入れたくなった場合に備えてクラスを分けておきます。

Projectウィンドウから「Assets/Scripts/Shop」のフォルダを開き、MonoBehaviourのスクリプトファイルを作成します。名前は [ShopEquipmentInformationWindowController] にしました。

パラメータ変動を表示するクラス
パラメータ変動を表示するクラス

 

作成した「ShopEquipmentInformationWindowController」の中身は以下のように記載しました。

現時点ではお店固有の処理がないので、継承して別クラスとして作成するのみにしてあります。

 

お店のアイテム画面を制御するクラス

次にお店のアイテム画面を制御するクラスを作成します。アイテム選択時のキー入力を検知して、ShopCommandで選択されている状態に応じて処理を分けていくようにします。

Projectウィンドウから「Assets/Scripts/Shop」のフォルダにて、MonoBehaviourのスクリプトファイルを作成します。名前は [ShopItemWindowController] にしました。

お店のアイテム画面を制御するクラス
お店のアイテム画面を制御するクラス

 

作成した「ShopItemWindowController」の中身は以下のように記載しました。

ここまでくるともっと共通化したり分割したりできたのでは……と思う部分はありますが、リファクタリングをしているとチュートリアルが終わらないので苦渋の決断でこのまま進めます(白目)

お店のアイテム画面のUIへの参照や、購入に関するアイテム制御クラスへの参照など、必要な参照をフィールドとして用意しています。この後作成するクラスについて参照用フィールドを用意しているので、コンパイルエラーが出るかと思いますが、今回の作業を完了させるときには消えるはずです。

選択中のインデックスや現在のページ数など、他のアイテム画面と共通したフィールドも使います。

InitializeControllers()では各種コントローラの初期化を行なっています。

Update()からはSelectItem()のメソッドを呼び、入力を検知しています。ShowNextPage()やShowPrevPage()は左右キーによるページ切り替え、SelectUpperItem()やSelectLowerItem()は上下キーによるカーソル移動を行います。

IsValidIndex()やIsValidSelection()ではインデックスの値や選択が正しいか検証を行なっています。これは購入、売却それぞれで参照するアイテムリストが異なるので、分岐させてそれぞれの検証用メソッドを呼び出しています。今回は購入処理に関する部分を実装しますが、次回売却処理について実装することから、売却を選択した際の分岐も作成してあります(処理内容は空欄)。

PostSelection()はキー入力に対応する操作を行なった後に呼び出されて、カーソルの表示やアイテムの説明文表示などを行います。また、アイテムの説明文表示を行うのに合わせて、選択したアイテムを装備した場合のパラメータ変動も表示するようにしています。装備品でない「薬草」を選択した場合は、変化がないことを示すため、現在の装備品のパラメータの値をそのまま表示するようにしています。

SetGoldValue()では所持金の値をセットしています。

OnPressedConfirmButton()は決定ボタンが押されたときに呼ばれ、「ShopManager」に選択されたアイテムの情報を渡し、確認メッセージを表示するようにします。

 

購入に関するアイテム制御のクラス

アイテム画面の制御のうち、購入に関する部分を制御するクラスを作成します。購入時は、イベントプロセスから渡された品揃えリストに沿ってアイテム名を表示します。画面に表示するアイテムに関するデータなどもフィールドとして保持して、選択されたインデックスに沿ったものを取得するようにします。

Projectウィンドウから「Assets/Scripts/Shop」のフォルダにて、MonoBehaviourのスクリプトファイルを作成します。名前は [ShopItemWindowBuyController] にしました。

購入に関するアイテム制御のクラス
購入に関するアイテム制御のクラス

 

作成した「ShopItemWindowBuyController」の中身は以下のように記載しました。

クラス内の大まかな構成としてはメニューのアイテム画面や魔法画面で個別の処理を行なっていたクラスと同様です。

InitializeItemInfo()のメソッドでは、品揃えリストからIDを確認してアイテムデータをリストに追加しています。

SetPageItem()のメソッドでは、アイテム名と価格をセットしていきます。

CanSelectItem()のメソッドでは、所持金が足りているか、アイテムの所持数が上限に達していないかを確認します。アイテムの所持数に関しては「ValueSettings」で定義してある「MaxItemNum」のフィールドを参照しています。

 

購入処理を行うクラス

選択されたアイテムに応じて所持金を減らして、所持アイテムを増やす処理を行うクラスも作成します。

Projectウィンドウから「Assets/Scripts/Shop」のフォルダにて、MonoBehaviourのスクリプトファイルを作成します。名前は [ShopProcessorBuy] にしました。

購入処理を行うクラス
購入処理を行うクラス

 

作成した「ShopProcessorBuy」の中身は以下のように記載しました。

BuySelectedItem()のメソッドの中で購入処理を行います。アイテム画面でアイテムを選択できるかどうかの検証は「ShopItemWindowBuyController」で行なっているので、このメソッドに渡された後はアイテムの増加、お金の減少処理を行います。

処理が完了したら、「ShopItemWindowBuyController」のOnFinishedItemProcess()に通知を行います。

 

既存のクラスの変更

今回作成したクラスと繋ぎ合わせるため、以下のクラスも変更していきます。

  • ValueSettings
  • ShopManager

 

ValueSettingsの変更

「ValueSettings」ではお店に関する定義値を追加します。

アイテムの売値を計算するための係数を「SellPriceMultiplier」として定義しました。この値をそのまま価格にかけるので、売却時は買値の半額になります。

この値を実際に使うのは次回のチュートリアルになります。

 

ShopManagerの変更

「ShopManager」ではアイテム購入時の確認処理などを追加します。

既存の「_mapMessageWindowController」のフィールドの下に、今回追加したクラスへの参照を追加します。

 

StartShopProcess()の中では、フィールドとして参照を保持するようにしたクラスのセットアップ処理を呼ぶようにしました。

 

既存のOnSelectedOption()のメソッドを変更し、その下にいくつかメソッドを追加しています。

OnSelectedItem()は購入時のアイテム画面で決定ボタンを押したときに呼ばれ、ShowBuyMessage()として購入確認メッセージを表示します。このときに通常の選択肢ウィンドウを表示して、「はい」なら購入処理のクラスのBuySelectedItem()を呼ぶようにします。

購入後はPostAction()としてコルーチンを起動して、メッセージウィンドウに「まいどあり!」と表示してお店のトップ画面に戻ります。「_isSecondVisit」の値をtrueにしているので、トップ画面に戻った後は「いらっしゃい!」ではなく、「他に必要なものはあるかい?」と2回目以降のメッセージを表示するようにします。

 

スクリプトのアタッチ

作成したスクリプトをアタッチしていきましょう。

Hierarchyウィンドウから「ShopManager」の子オブジェクトとして空のゲームオブジェクトを4つ作成します。名前はそれぞれ [ShopEquipmentInformationWindowController][ShopItemWindowController][ShopItemWindowBuyController][ShopProcessorBuy] にしました。

ゲームオブジェクトの作成
ゲームオブジェクトの作成

 

それぞれ順番にスクリプトをアタッチしていきます。「ShopEquipmentInformationWindowController」のゲームオブジェクトでは同名のスクリプトファイルをアタッチし、UI制御のクラスもアサインします。ゲームオブジェクト名が同じになっているので、「ShopScreen」の下にあるものをドラッグ&ドロップすると安心です。

装備によるパラメータ変動を表示するクラス
装備によるパラメータ変動を表示するクラス

 

次に「ShopItemWindowBuyController」に同名のスクリプトファイルをアタッチします。

アイテム画面の購入に関する処理
アイテム画面の購入に関する処理

 

「ShopProcessorBuy」に同名のスクリプトファイルをアタッチします。

購入処理を行うクラス
購入処理を行うクラス

 

「ShopItemWindowController」についても同名のスクリプトファイルをアタッチします。他のクラスへの参照もアサインしましょう。

アイテム画面を制御するクラス
アイテム画面を制御するクラス

 

「ShopManager」にもフィールドを追加したので、こちらも参照をアサインしておきましょう。

参照のアサイン
参照のアサイン

 

UIの修正

以前作成したUIですが、アイテムの説明文を表示するウィンドウが2つ存在しているので、装備によるパラメータ変動のウィンドウ内のものを非表示にします。今回の実装だと「ItemDescriptionBackground」側の説明文を変えていたのですが、それより手前に表示される「EquipmentInformationParent」側の説明文が変わらずに動作していないように見える状態になっていました(1敗)

アイテムの説明文ウィンドウを非表示に
アイテムの説明文ウィンドウを非表示に

 

動作確認

アイテムを買う時のお店の動作を確認してみましょう。確認前に、「Map_0001_Village」を非表示に、「ShopItemParent」も非表示にしておきます。

宝箱からお金を入手して、店主のおっちゃんに話しかけます。お店の選択肢では「買う」を選択し、

  • ゴールドの足りているアイテムが買えること
  • 武器または防具にカーソルを合わせるとパラメータ変動が表示されること
  • 購入したアイテムがメニューのアイテム画面から確認できること
  • 購入後のゴールドが正しいこと
  • アイテムの所持数が99個の場合はそのアイテムを購入できないこと

を確認しましょう。

アイテムの所持数については「CharacterStatusSetter」で変更可能です。例えばゲーム開始時に薬草を98個持たせておいて、98個の時点では購入できること、購入後、薬草が99個になったらそれ以上購入できないことを確認できます。

アイテム購入の確認
アイテム購入の確認

 

今回はたくさんスクリプトを作成したので、Null参照などが発生したら、スクリプトのアタッチや参照のアサインの部分をご確認ください。

 

今回のブランチ

 

まとめ

今回はお店でアイテムを買う動作を実装しました。アイテム購入の機能はRPGだとほとんど実装されているかと思いますので、一度テンプレートのような形で作っておくと使いまわして改造するのに便利です。

次回はお店でアイテムを売る動作を実装していきます。

     

ゲーム開発の攻略チャートを作りました!

CTA-IMAGE

「ゲームを作ってみたいけど、何から手を付けていいか分からない!」


そんなお悩みをお持ちの方向けに、todoがアプリをリリースした経験を中心に、ゲーム作りの手順や考慮すべき点をまとめたe-bookを作成しました。ゲーム作りはそれ自体がゲームのように楽しいプロセスなので、「攻略チャート」と名付けています。


ゲームを作り始めた時にぶつかる壁である「何をしたら良いのか分からない」という悩みを吹き飛ばしましょう!