ユニティちゃんのRPGを作ってみよう11ーアイテムコマンドの作成ー

今回はコマンド画面にアイテムコマンドを追加していきたいと思います。

機能が複雑なのと、この記事自体が長いので今回はアイテムコマンドをどうやって実現しようとしているか?とスクリプトの中身を把握しながら作って頂けると助かります。

単純に記事も長いのでわかりずらいです。

おそらくコピペで手っ取り早く機能だけ取り付けるというわけにはいかないのでご了承ください。

前回はコマンド画面の作成とステータスコマンドを作成しました。

ユニティちゃんのRPGでコマンド画面の作成とステータスコマンドを作成し、選択したキャラクターのステータスを表示するようにしていきます。

ユニティちゃんのRPGを作ってみようの他の記事は

から見ることが出来ます。

スポンサーリンク

アイテムコマンドの概要

前回ステータスコマンドを作成したのと同じようにアイテムコマンドを作成していきます。

ただし、アイテムコマンドの場合は

アイテムコマンドの選択→どのキャラクターの持っているアイテムかの選択→アイテム一覧表示→選択したアイテムの種類に応じて装備や使用等の選択→アイテム使用や渡す場合は使用するキャラクターの選択

という流れで条件に応じて新しいパネルをどんどん開く必要があります(昔のドラクエ風)。

今回はパネルを複数作成し、状況に応じてどんどん手前に表示する仕様にしたので、そうなりますが画面全体で情報を表示する場所を決めておき、パネルが重ならないようにするという方法もあります。

UIの作成は上の流れに沿って作成していく事にします。

アイテム一覧は持っているアイテムの種類分のボタンをプレハブからインスタンス化し表示する必要があり、表示領域をスクロールする必要があります。

スクロールバーを用意してマウスでスクロールする場合は問題ないですが、PS3コントローラー等のゲームコントローラーでアイテムを選択する場合は自動でアイテムボタン表示領域をスクロール出来ません。

スクロールバーにフォーカスを移動出来るようにすれば出来ない事もないですが、これはやめておきます。

そこで1回で表示出来るアイテムは何個か決めておいてその表示している最後のボタンの次のボタンを選択したら自動で表示領域がスクロールされるようにします。

現時点では何を言ってんの?と思われるかもしれませんが、アイテム一覧の機能を作った時にわかります。

アイテムコマンドUIやアイテムコマンドの処理が複雑かつ長くなったのでアイテム一覧のスクロール機能は次回作成していきます。

ステータスコマンドの時よりもUIのパネルの数が増えてたり、処理が複雑になっているので注意してください。(´Д`)

エラーが出ないという事は保証しません・・・・(´Д`)

あくまでこういった作り方で出来ましたというわたくしの実験みたいなものです・・・(´Д`)

前回のステータスコマンドや今回のアイテムコマンド、このユニティちゃんのRPGを作ってみようのカテゴリ全般でアイテム一覧等はボタンのプレハブをその数分インスタンス化しています。

ですが、あらかじめボタンをヒエラルキー上に配置しておく方法もあります(こちらの方が処理速度が速いかも?)。

やり方に関してはこの記事の最後に記載しますが、既にボタンのプレハブをインスタンス化する方法で作ってしまった為、あらかじめボタンを配置して作る方法を個別に詳細に説明はしません。(´Д`)

アイテムコマンドUIの作成

アイテムコマンドで使用するボタンやパネルを作成していきます。

アイテムコマンドのパネル構成

アイテムコマンドを選択した後のパネルの構成と流れを図にしました。

ユニティちゃんRPGのアイテムコマンドのパネルの遷移

スクリプトで現在どういう状況なのかを保持しておき、それを元に次のパネルを開いたりCancelボタンを押した時に元のパネルに戻ったりを実行します。

前のパネルで選択したボタンはselectedGameObjectStackにどんどんプッシュしていき、前のパネルに戻った時にポップして取り出し、前のパネルでどのボタンを選択していたかを把握しそのボタンをフォーカスします。

アイテムを選択した状態ではアイテムの使用や渡す、捨てるといったコマンドを表示(UseItemPanel)し、それらを実行した後もそのアイテム数が0より多い場合はそのままUseItemPanelでアイテムをどうするかを選択します。

UseItemPanelの捨てるを選択した時やアイテムを使用や渡す相手を選択するUseItemSelectCharacterPanelでキャラクターを選択した後にそのアイテムが0になり、かつそのキャラクターが他のアイテムも一つも持っていない場合はSelectCharacterPanelに処理を移します。

そのアイテム自体がなくなっても他のアイテムを持っていればItemPanelに戻ります。

アイテムコマンドボタンの作成

アイテムコマンドを実行する為のボタンを作成します。

Command→CommandPanelの子要素のStatusButtonを選択し、Ctrl+Dキーで複製し名前をItemButtonとします。

ItemButtonのButtonのOn ClickでCommandScriptのSelectCommandメソッドを呼び出した時の引数はItemに変更します。

ユニティちゃんRPGのアイテムコマンドの選択ボタンのインスペクタ

ItemButtonを押した時はCommandScriptのSelectCommandでアイテムコマンドの処理がされるように後で処理を追加します。

アイテムを表示するキャラクター選択パネルの作成

ItemButtonを押したら次はどのキャラクターのアイテムを表示するかのパネルを表示する必要があります。

これはステータスコマンドでどのキャラクターのステータスを表示するか?というSelectCharacterPanelと同じなのでSelectCharacterPanelを使用することにします。

アイテム一覧表示パネルの作成

どのキャラクターのアイテムを表示するかのボタンを押したら次はそのキャラクターが持つアイテムの一覧とアイテム数等を表示するアイテム一覧パネルを表示する必要があります。

Commandゲームオブジェクトを選択した状態で右クリックからUI→Panelを選択しItemPanelという名前にします。

ItemPanelのサイズは

ユニティちゃんRPGのItemPanelのサイズ

上のような感じにしました。

ItemPanelのImageコンポーネントの横のチェックを外し、表示しないようにします。

ItemPanelのインスペクタについては後で変更しますので、その時に画像で設定を紹介します。

アイテム一覧のマスク領域の作成

ItemPanelを選択した状態で右クリックからUI→Panelを選択し、名前をMaskとします。

MaskのインスペクタのAdd ComponentからUI→Maskを選択し取り付けます。

ユニティちゃんRPGのItemPanel子要素のMaskの設定

このMaskゲームオブジェクトはMaskコンポーネントを取り付けているので子要素のアイテムボタンやテキスト等が範囲外(Mask領域外)に出た時は表示されなくなります。

アイテムパネルボタンを表示する領域の作成

Maskを選択した状態で右クリックからUI→Panelを選択し、名前をContentとします。

Anchor Presetsからtop stretchにし開始位置はMaskの上、横幅はMaskの幅にし、Heightを3000としておきます。

Heightの値はアイテム一覧全体の長さになるので、アイテムを表示する数に応じて数値をより大きくする必要があります。

ContentのインスペクタのAdd ComponentからLayout→Grid Layout Groupを取り付け以下のように設定します。

ユニティちゃんRPGのItemPanelの子要素のContentの設定

Grid Layout Groupはグリッドで子要素のコンテンツを整列させることが出来ます。

Cell Sizeで子要素のゲームオブジェクト(個々のアイテムボタン)のサイズを設定し、ConstraintsでFixed Column Countに設定し、Countを2にして横に2個アイテムボタンを表示したら下に表示するようにします。

個々のアイテムを表すItemPanelButtonプレハブの作成

Contentの子要素に配置する個々のアイテムを表すItemPanelButtonプレハブを作成していきます。

Contentを選択した状態で右クリックからUI→Buttonを選択し、名前をItemPanelButtonとします。

Imageのチェックを外し、ButtonのTransitionをNoneにします。

ItemPanelButtonも選択した時に音を鳴らしたいのでCommandPanelButtonScriptとAudio Sourceコンポーネントを取り付け鳴らす音をAudio Clipに設定します。

また新しくItemPanelButtonScriptスクリプトを作成し取り付けます。

ユニティちゃんRPGのItemPanelの子要素に表示する個々のアイテムボタンのプレハブ

ItemPanelButtonScriptは以下のように作成します。

SetParamメソッドはCommandScriptメソッドから呼び出してアイテムボタン個々でアイテム情報を保持し、アイテムパネルボタンが選択されたらアイテム情報を表示します。

ItemPanelButtonの子要素にUIのImageとTextを4つ作成し、Textの名前をEquip、ItemName、Multiply、Numと変更します。

ユニティちゃんRPGのItemPanelButtonの階層

Imageはボタンを選択した時のアイコンの設定でStatusButtonやItemButtonと同じです。

Equipは装備している武器や鎧である場合にEを表示するのに使い、ItemNameはアイテム名、Multiplyはアイテムの個数を表す×を表示し、Numにはアイテムの個数を表示します。

配置としては以下のようになります。

ユニティちゃんRPGのItemPanelButtonの実際の画像

Equip、MultiplyのAlignmentは中央にし、ItemNameは左揃え、Numは右揃えにしておきます。

ItemPanelButtonは親のContentのGrid Layout Groupでセルのサイズを指定しているので、Widthを300、Heightを50にし、子要素のImageやテキスト群はそれに合わせてWidthとHeightを調整したり位置を調整してください。

ここまで出来たらItemPanelButtonをAssets/RPG/Prefabs/UI/Commandフォルダ内にドラッグ&ドロップしてプレハブにします。

ヒエラルキー上のItemPanelButtonはこの後使いますので残しておきます。

アイテムパネルボタンをとりあえず並べてみる

アイテムパネルボタンがどのように表示されるかを確認する為に、ヒエラルキー上のItemPanelButtonをCtrl+Dキーで複製し20個に増やしてみます。

するとシーンビューでは以下のように表示されます。

ユニティちゃんRPGのItemPanelの子要素にItemPanelButtonを並べてみた画像

アイテムが表示されるのはMaskパネルの領域だけなのでアイテムボタンが16個までしか表示されず、その下のアイテムボタンは見えません(ItemPanelのサイズによって数は変わります)。

また表示されている15個目と16個目のアイテムボタンは少し切れています。

そこでMaskパネルの領域を少し狭めてアイテムが14個まで完全に表示される状態にします。

ユニティちゃんRPGのItemPanelの子要素のMask領域を調整する

これでとりあえず1回に見える範囲は14個のアイテムだけになりました。

アイテム一覧をマウスでスクロール出来るようにする

アイテム一覧をマウススクロールするにはScroll RectコンポーネントとScrollbarが必要になります。

ItemPanelのインスペクタでAdd ComponentからUI→Scroll RectとLayout→Canvas Groupを取り付けます。

ItemPanelを選択した状態で右クリックからUI→Scrollbarを選択します。

ScrollbarのRect TransformのAnchor Presetsでmiddle rightにしWidthを20、Heightを160とします(WidthとHeightは任意です)。

ScrollbarのDirectionをBottom To TopにしValueを1とします。

ユニティちゃんRPGのアイテムパネルのスクロールバーの設定

次にItemPanelに取り付けたScroll Rectコンポーネントの設定をします。

ContentにはMaskの子要素のContentゲームオブジェクトを設定し、Movement TypeをClampにします。ClampにするとContentゲームオブジェクトの子要素のアイテムボタンの表示領域で制限されて動きます。

マウスでスクロールする場合はContentの領域内で動きます。

Vertical Scrollbarに先ほど作ったScrollbarゲームオブジェクトを設定します。

ユニティちゃんRPGのItemPanelのScroll Rectの設定

上ではCanvas Groupのinteractableのチェックを外していますが、これはスクリプトから有効と無効を切り替えるので最初は無効としておく必要があります。

ただ今はマウスでスクロールするのを確認したいのでinteractableにチェックを入れます。

これでContent領域をマウスでドラッグしたり、スクロールバーをドラッグすることでアイテム一覧の領域を移動出来るようになりました。

ユニティちゃんRPGのアイテム一覧をスクロールバーでスクロールするサンプル

ただ、ゲームコントローラーでアイテムを選択して下に移動していってもアイテム一覧はスクロールしてくれません。

とりあえずゲームコントローラーでアイテム一覧をスクロールするやり方は次回作成するので、UIの続きを作成していきましょう。

ItemPanel子要素のContent以下に作成したItemPanelButton達は全て削除し、Content以下には何もゲームオブジェクトがないようにします。

またItemPanelのCanvas Groupのinteractableのチェックを外しておきます。

アイテムを選択した時に表示するパネルの作成

アイテム一覧パネルでアイテムボタンを押した時に表示するパネルを作成します。

Commandを選択した状態で右クリック→Panelを選択し、名前をUseItemPanelとします。

表示領域は以下のようにしました。

ユニティちゃんRPGのUseItemPanelの表示領域

UseItemPanelのインスペクタのAdd CompoenntからLayout→Canvas GroupとLayout→Vertical Group Layoutを取り付けます。

設定については今まで作成してきたパネルと同じです。

ユニティちゃんRPGのUseItemPanelのインスペクタの設定

次にUseItemPanelの子要素にAssets/RPG/Prefabs/UI/Command/CharacterButtonをドラッグ&ドロップします。

今ドラッグ&ドロップしたCharacterButtonを選択した状態で右クリックからUnpack Prefab Completelyを選択しプレハブとのリンクを解除し普通のゲームオブジェクトにします。

そしたら名前をUseItemButtonとし、Assets/RPG/Prefabs/UI/Commandフォルダにドラッグ&ドロップしてプレハブにします。

プレハブにしたらヒエラルキー上のUseItemButtonは削除します。

アイテムを使うキャラクター選択パネルの作成

次にアイテムを選択した時に表示したパネル(UseItemPanel)で『使う』や『渡す』を選択した時に表示する誰にアイテムを使うのか?を表示するパネルを作成します。

UseItemPanelゲームオブジェクトを選択しCtrl+Dキーで複製し、名前をUseItemSelectCharacterPanelとします。

UseItemSelectCharacterPanelの領域は以下のようにしました。

ユニティちゃんRPGのUseItemSelectCharacterPanel

UseItemSelectCharacterPanelに表示するボタンはSelectCharacterPanelと同じCharacterButtonなので特に作成しません。

アイテム情報の情報を表示するパネルの作成

アイテム情報を表示するパネルを作成していきます。

Commandを選択した状態で右クリックからUI→Panelを選択し、名前をItemInformationPanelとします。

ItemInformationPanelの子要素にUI→Textを二つ作成し、名前をTitleとInformationにし、以下のような領域にします。

ユニティちゃんRPGのInformationPanelの領域

Titleにはアイテムのタイトル、Informationにはアイテム情報やアイテムを使用した時の情報を表示します。

アイテムの装備や使用等をした時の情報表示パネルの作成

アイテムの装備や使用等をした時にもItemInformationPanelのInformationのテキストに表示しようと思ったんですが、ItemPanelButtonScriptでボタンが選択された時にアイテム情報を更新しているので、これがうまく出来ません。

そこでアイテムを装備や使用した時は別のパネルを作りそこに情報を表示しようと思います。

Commandを選択した状態で右クリックからUI→Panelを選択しUseItemInformationPanelとし子要素にUI→Textを作成します。

TextのAnchor Presetsでstretch stretchにしUseItemInformationPanelの大きさに応じてTextの幅も変えます。

TextのFont Sizeは30にしました。

UseItemInformationPanelは以下のような位置とサイズにしました。

ユニティちゃんRPGのUseItemInformationPanel

これでアイテムコマンドに関するUIの作成が完了しました。

CommandScriptにアイテムコマンドの処理を追加する

UIが出来たので後はItemButtonを押した後のアイテムコマンドの処理をCommandScriptに追加していくだけです。

追加していくだけですと言うと簡単なように思えますが、処理は面倒な事をしています。(^_^;)

CommandModeにモードを追加する

まずはCommandModeにモードを追加します。

  • 持っているアイテムを表示するキャラクターのパネルを開いた状態(ItemPanelSelectCharacter)
  • アイテム一覧のパネルの状態(ItemPanel)
  • アイテムの使用や渡す、捨てる等を表示するパネルの状態(UseItemPanel)
  • 使用するアイテムを使うキャラクター選択のパネルの状態(UseItemSelectCharacterPanel)
  • アイテム装備、装備を外すをした後の状態(UseItemPanelToItemPanel)
  • アイテムを捨てるを選択した後にまだそのアイテムがある状態(UseItemPanelToUseItemPanel)
  • アイテムを使用、渡すを選択した後に使用する、渡す相手を選択した後の状態(UseItemSelectCharacterPanelToUseItemPanel)
  • アイテムを使用、渡す、捨てるを選択した後にそのアイテムが0になり他のアイテムも一つも持っていない状態(NoItemPassed)
  • になります。

    フィールド宣言

    フィールドを追加します。

    作成したパネルのフィールドやテキスト、アイテムボタンや使用するアイテムのボタンのプレハブを作りプレハブにはインスペクタで設定する必要があります。

    itemPanelButtonListにはアイテム一覧に表示したボタンのゲームオブジェクトを登録しておき、武器を装備した時や外した時にアイテムの名前の前のEquipを表すEの文字を表示したり消したりする時に使用します。

    Awakeメソッドに処理を追加

    Awakeメソッドにフィールドに設定するゲームオブジェクト等の取得をする処理を追加します。

    行っていることは階層を辿って該当するゲームオブジェクト、CanvasGroup、Textを取得しているだけです。

    OnEnableメソッドに処理を追加

    OnEnableメソッドにパネルの非表示等の処理を追加します。

    Commandがアクティブになった時に以前作成したボタンの削除、リストのクリア、CanvasGroupの初期化を行っています。

    Updateメソッドに処理を追加する

    Updateメソッドに処理を追加していきます。

    Cancelボタンを押した時の処理

    UpdateメソッドでCancelボタンが押された時に現在どのコマンドモードかを調べ処理を分岐させている所に新しく追加した状態の条件を加えます。

    やっていることは同じなので割愛します。

    ほとんど同じ処理をしているのでメソッドに切り分けることも出来そうです。

    が、ややこしくなるので同じような記述をズラズラと書いています。

    アイテム使用後の情報を消し次の事を行う為の処理

    アイテムを装備、装備を外す、使用、渡す、捨てるといった事を行ったらUseItemInformationPanelの子要素のTextに何をしたか?の情報を載せます。

    その情報を載せた状態で何らかのキーを押した時に次の動作に移行させる為の処理を記述します。

    アイテムをどうするか?をUseItemPanelで選択した後にどうしたのか?の情報をUseItemInformationPanelに表示していますが、その後に何らかのキーを押したらUseItemInformationPanelを非表示にしてから次の行動が出来るようにしています。

    currendCommandの状態に応じてキーが押されたらどのパネルのCanvasGroupのinteractableを操作して、どのパネルをアクティブにするか等の処理をしています。

    Input.anyKeyDownはUnityメニューのEdit→Project Settings→InputのTypeでKey or Mouse Buttonであるボタンが押された時、キーボードのキーを押した時マウスボタンを押した時等にtrueになります。

    なのでゲームコントローラーのジョイスティックや十字キー等のInputのTypeがJoystick Axisの場合は反応しません。

    そういったものも反映させる為に!Mathf.Approximately(Input.GetAxis(“Horizontal”), 0f)等の条件を加えて、十字キーやジョイスティックが少しでも押されていたら条件が成立するようにしています。

    SelectCommandメソッドに処理を追加する

    SelectCommandにItemButtonを押した時に処理をする部分を追加します。

    SelectCommandはCommandPanelのボタンが押された時の処理をしていました。

    送られてきた文字列がStatusの時のif分の下にItemの時の処理を追加します。

    行っていることはStatusの時とほとんど同じで作成したボタンが押された時にCreateItemPanelButtonメソッドを呼び出すだけです。

    AddListenerの引数にはラムダ式を指定し、ボタンがクリックされたら無条件にCreateItemPanelButtonメソッドに引数memberを渡して呼び出します。

    ラムダ式については

    C#のデリゲートとラムダ式をUnity付属のMonoDevelopで使用してみます。

    を参照してください。

    CreateItemPanelButtonメソッドの作成

    CreateItemPanelButtonメソッドはどのキャラクターのアイテムを表示するかのボタンを押した時に実行されるメソッドです。

    どのキャラクターのアイテムを表示するかの選択がされた後の処理なのでItemPanelを表示し、そこに個々のアイテムを表すItemPanelButtonプレハブからインスタンスを生成していきます。

    アイテム一覧を表示するのでitemInformationPanelを表示し、アイテムを選択した時にそのアイテムの情報を見れるようにします。

    前のパネルのCanvasGroupであるselectCharacterPanelCanvasGroupはfalseにしSelectCharacterPanelのボタンは選択出来ないようにします。

    allyStatus.GetItemDictionary().Keysでそのキャラクターが持っているアイテムのキーが全て取得出来るのでforeachを使って全部のアイテムのボタンを作成していきます。

    ItemPanelButtonPrefabはItemPanelの子要素のContentゲームオブジェクトの子要素としてインスタンス化します。

    インスタンス化したボタンの子要素からItemNameという名前のゲームオブジェクトのTextコンポーネントを取得し、item.GetKanjiName()でアイテムの漢字名を取得し入れています。

    アイテム一覧にインスタンス化したアイテムパネルボタンが押された時はそのアイテムについて何らかの行動をする必要がありそれを設定しているのが、

    の処理です。

    今プレハブからインスタンス化したItemPanelButtonPrefabのButtonコンポーネントを取得しonClick(ボタンを押した時)にAddListenerメソッドを使って実行するメソッドを登録しています。

    アイテムパネルボタンを押した時はSelectItemメソッドに引数allyStatus(そのキャラクターのステータス)とitem(このボタンを表しているアイテム)を渡します。

    ItemPanelButtonPrefabにはあらかじめItemPanelButtonScriptを取り付けてあるのでSetParamメソッドを使ってItemを渡しています。

    アイテムパネルボタンにはアイテムの数とそのアイテムが装備している武器や鎧だった時はEを表示する箇所があるので、情報を取得してそれを設定しています。

    アイテムパネルボタンのインスタンスが出来たらitemPanelButtonListに登録しておきます。

    アイテム一覧にアイテム数分のアイテムパネルボタンが出来たらContentの最初の子要素を選択している状態にします。

    もしキャラクターがアイテムをひとつも持っていなければ情報を表示し、SelectCharacterPanelに戻ります。

    SelectItemメソッドの作成

    次にアイテム一覧に表示した個々のアイテムボタンを押された時に実行するSelectItemメソッドを作成していきます。

    SelectItemメソッドではそのアイテムに対してどういった操作が可能かを判断しUseItemPanelに対応するボタンを作成します。

    アイテムの種類に応じて選択出来る項目のタイトルやボタンを押された時に実行するメソッドの設定を変えています。

    アイテムが装備品の場合で既に装備している装備品であれば『装備を外す』(RemoveEquipメソッド)、装備していなければ『装備する』(Equipメソッド)、『渡す』(PassItemメソッド)『捨てる』(ThrowAwayItemメソッド)をぞれぞれ実行します。

    回復アイテム(Item.Type.Recovery)、状態回復アイテム(Item.Type.NumbnessRecovery、Item.Type.PoisonRecovery)の場合は『使う』(UseItemメソッド)、『渡す』『捨てる』ボタンを表示します。

    貴重品(Item.Type.Valuables)の場合は情報表示パネルにアイテム情報を表示するだけです。

    貴重品以外のアイテムであればcurrentCommandを変更し、現在選択しているボタンをselectedGameObjectStackにプッシュし、UseItemPanelの最初のボタンを選択状態にします。

    Input.ResetInputAxes()メソッドはそのフレームでの入力をリセットし同じフレーム内で連続してキーやボタンが押されたと判断されない為に入れています。

    UseItemメソッドの作成

    選択したアイテムをどうするか?の『使う』ボタンを押した時に実行するUseItemメソッドを作成していきます。

    選択したアイテムを『使う』という選択をしたので、現在選択している『使う』ボタンをselectedGameObjectStackにプッシュし、UseItemSelectCharacterPanelにパーティーメンバー分のボタンをプレハブからインスタンス化し、そのボタンが押された時にUseItemToCharacterメソッドが実行されるようにします。

    アイテムを使う事にしたので誰に使うか?のボタンを表示するUseItemSelectCharacterPanelの子要素に表示するボタンの作成とそのボタンを押した時に実行するメソッドを指定しています。

    UseItemToCharacterメソッドの作成

    アイテムを使うキャラクターを選択した時に実行するUseItemToCharacterメソッドを作成します。

    使うアイテムの種類に応じて処理を分けています。

    例えば使ったアイテムが回復アイテムならば相手のキャラクターのHPが最大かどうかを判断し、最大であれば使う必要がないのでその情報を表示し、少しでも体力が減っていれば回復し、アイテムを使ったキャラクターのアイテムのアイテム数を減らします。

    状態回復の場合は相手のキャラクターの状態を見て、同じように状態異常でなければその情報を表示し、状態異常であれば回復し使ったキャラクターのアイテムのアイテム数を減らします。

    アイテムを使用したらUseItemPanelに戻るのでUseItemSelectCharacterPanelの子要素に作ったキャラクター選択のボタン群は削除します。

    このままだとItemPanelのアイテム一覧のアイテム数が減らないので、

    itemPanelButtonListにあらかじめ入れておいたItemPanelButton達の中からボタンの子要素のItemNameテキストの文字列と現在のアイテムの漢字名を比較して抽出し、そのボタンのNumテキストのアイテム数を更新しています。

    上の場合ではアイテムパネルボタンのItemNameテキストに表示する名前が被っていない事を前提としています。

    最後に使用したアイテムの数が0だったらUseItemPanelではなくItemPanelまで戻すのでその処理を行っています。

    selectedGameObjectStackから不要となったボタンをポップし、itemPanelボタンに表示されているそのアイテムのボタンを削除します。

    またキャラクターが持っているアイテムのItemDictionaryからそのアイテムを削除します。

    ItemPanelに戻るのでUseItemPanelの子要素に作成したアイテムをどうするか?のボタン群を全て削除します。

    使用したアイテムの数が残っている場合はUseItemPanelに戻り、そのアイテムをどうするか?の選択に戻ります。

    アイテム数が残っている場合はcurrentCommandにCommandMode.UseItemSelectCharacterPanelToUseItemPanelを設定し、useItemInformationPanelにアイテムを使用した旨を表示します。

    『アイテム使用後の情報を消し次の事を行う為の処理』の項目で説明されていますが、アイテムを使用、渡す、捨てる、装備する、装備を外す等をした時にuseItemInformationPanelにそれらの情報を表示し、一度何らかのキーやボタンが押されたら他のパネルに移動するようになっています(currentCommandは違う)。

    PassItemメソッドの作成

    次はアイテムを『渡す』のボタンを押した時に実行するPassItemメソッドを作成します。

    PassItemメソッドはそのアイテムを誰に渡すか?をUseItemSelectCharacterPanelの子要素にボタンとして表示しますが、アイテムを渡す相手から自分自身を排除します(ユニティちゃんなら大鳥ゆうじにしか渡さない)。

    作成したボタンを押した時に実行するメソッドはPassItemToOtherCharacterメソッドを設定します。

    PassItemToOtherCharacterメソッドの作成

    アイテムを『渡す』を選択した後に、UseItemSelectCharacterPanelの子要素のボタンを押して渡す相手のキャラクターを選択した時に実行するPassItemToOtherCharacterメソッドを作成します。

    渡したキャラクターのアイテム数を減らし、アイテムを渡す相手がそのアイテムを持っていなければそのキャラクターのItemDictionaryにそのアイテムを登録します。

    その後に渡されたキャラクターのアイテム数を増やします。

    アイテムを渡し終わった時もアイテムを使用した時と同じで、アイテム数が0であればItemPanel、アイテムが残っていればUseItemPanelに移動します。

    アイテムが装備品で渡すキャラクターが1つしかそのアイテムを持っていない時は装備を外す必要があります。

    やっていることはほとんど『使用』と同じなので問題はないと思います。

    ThrowAwayItemメソッドの作成

    アイテムを『捨てる』を選択した時に実行するThrowAwayItemメソッドを作成します。

    こちらもアイテム数を減らしたり、減らした後のアイテムの数を見て戻るパネルを選択しているだけで行っていることは『使用』『渡す』と同じです。

    ただアイテムが0の時の処理の流れが『渡す』と変わってますね・・・・・(^_^;)

    最初の方にアイテム数が0の時の処理をしてますが、最後の方でもアイテム数が0の時で判定しているのでそこに移してもいいかもしれません(『渡す』の方はそうしているかも)。

    Equipメソッドの作成

    アイテムを『装備する』ボタンを押した時に実行するEquipメソッドを作成していきます。

    スクリプトが長くなっていますが、やっていることはそのキャラクターが装備できるものかどうかを判断し、装備出来ればItemPanelのアイテムパネルボタンの横に『E』を表示し、装備していた装備品の装備を外しているだけです。

    縦にも横にもスクリプトが長いので難しそうな処理をしてそうですが、やっていることは今までと同じです。

    RemoveEquipメソッドの作成

    アイテムの『装備を外す』ボタンを押した時に実行するRemoveEquipメソッドを作成します。

    鎧か武器かで判断しキャラクターの装備から外します。

    UIの外をマウスクリックした時の処理

    今のままだとマウスのクリックでコマンドの選択をする時にボタン外をクリックするとボタンの選択が解除されてしまいます。

    そこでEventSystemの選択が解除された時に現在のcurrentCommandに応じてそのパネルの一番最初の子要素を無理やり選択状態にし、選択が解除されている状態がないようにしておきます。

    Updateメソッドの最後に以下の処理を追加します。

    EventSystem.current.currentSelectedGameObjectがnullの時はUIが選択されていない状態なので、その時のcurrentCommandの状態を見て、該当するパネルの最初の子要素を無理やり選択させるようにしています。

    アイテム一覧にあらかじめボタンを配置しておく方法

    この記事の最初の方で言及しましたが、この記事を含めてユニティちゃんのRPGを作ってみようのカテゴリ全般でUIのパネルに表示するボタンをプレハブからインスタンス化しています。

    ですがこの方法だと今開いているパネルの前のパネルに戻った時にインスタンス化したボタンを全部削除する処理が必要になります。

    なのでアイテム数が多くなったり頻繁にキャンセルボタンを押して戻って選択して戻ってという処理を繰り返すと無駄にボタンのゲームオブジェクトの削除と生成を繰り返します。

    そこでアイテム一覧等にあらかじめボタンを配置しておいてあらかじめあるボタンを操作してボタンの子要素のTextやボタンを押した時の動作を設定した方がいいかもしれません。

    わたくしの場合は最初にボタンプレハブをインスタンス化する方法で作ってしまったのでもう書き換えませんが・・・・(^_^;)

    あらかじめボタンを配置しておくやり方を書いておきます。

    キャラクター選択パネルなどでもあらかじめボタンを配置しておくことが出来ますが、個数が多いアイテム一覧を例にとっています。

    まずはItemPanelの子要素のContentにAssets/RPG/Prefabs/UI/ItemPanelButtonプレハブをゲーム内で使用するアイテムの総数分作成します(持っているアイテムより少なく作ってはいけません)。

    ユニティちゃんRPGのItemPanel子要素のContentにあらかじめItemPanelButtonを配置しておく

    次にアイテム一覧で一回に表示されるアイテムボタンの次の二つのボタン(15個目と16個目のボタン)にItemPanelScrollScriptを取り付けます。

    CommandScriptスクリプトからItemPanelScrollScriptのSetScrollValueメソッドを呼び出してスクロール値等を渡して設定していましたが、既にボタンは配置しているのでItemPanelScrollScriptであらかじめ値を設定してしまいます。

    次にCommandScriptのOnEnableメソッドでアイテムパネルボタンがあれば削除していた箇所をコメントにするか削除します(消す必要がなくなったからです)。

    Updateメソッドのキャンセルボタンを押した時の処理でも同様にアイテムパネルボタンを削除している所をコメントにするか削除します。

    キャラクターが持っているアイテムのボタンを表示しているCreateItemPanelButtonメソッドを修正します。

    ItemPanelButtonPrefabをインスタンス化していた箇所を

    としてcontentの子要素のゲームオブジェクトを順番に取得するようにします。

    以前アイテム一覧を開いた時に持っているアイテムの数より後のボタンは非表示にしている可能性がある為、アクティブにしておきます。

    ボタンには依然開いた時にボタンを押した時に実行するメソッドが設定されている可能性があるので

    でボタンを押した時に実行する処理を削除します。

    あらためてボタンが押された時にSelectItemメソッドの呼び出し処理の追加と引数を設定します。

    アイテムのボタンはインスタンス化するか元から配置しているものを使うかの違いだけなので大きな変化はありません。

    ただItemPanelButtonは持っているアイテム数以上に配置したのでアイテム数を超えた場合はその後のアイテムボタンは非表示にします。

    アイテムを一個も持っていない時のif文の条件は

    という条件に変更します。

    これであらかじめItemPanelButtonを配置しても同じような処理に出来ました。

    アイテムコマンドの確認

    これで機能が出来ました。

    実行して試してみましょう。

    上のようにアイテムコマンドが出来上がりました。

    終わりに

    今回のアイテムコマンドの処理は非常に面倒な処理が多いですね・・・・。

    処理も分かり辛くなってますし・・・・、量が多いのでどこか記述漏れや間違いがあるかもしれません。(._.)

    前回のステータスコマンドと今回のアイテムコマンドはパネルを開いてそのパネルを最前面に表示しコマンド処理をしていますが、Animationを使ってUI画面が動くように作るとまた違った良さが出そうですね。

    ユニティちゃんライセンス

    この作品はユニティちゃんライセンス条項の元に提供されています

    スポンサーリンク

    記事をシェアして頂ける方はこちら

    フォローして頂くとやる気が出ます