ユニティちゃんのRPGを作ってみよう12ーアイテム一覧のスクロール機能ー

今回は前回作成したアイテムコマンドのアイテム一覧表示でキーボードやゲームコントローラー操作でアイテム一覧をスクロールする機能を作成していきます。

前回はコマンド画面にアイテムコマンドを作成しました。

ユニティちゃんのRPGを作ってみよう11ーアイテムコマンドの作成ー
ユニティちゃんRPGのコマンド画面でアイテムコマンドの作成とアイテムの装備や使用、渡す、捨てる等が出来るようにしていきます。

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

ユニティちゃんのRPGを作ってみよう
ユニティちゃんのRPGを徐々に作っていくカテゴリです。

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

前回作成したアイテムコマンドのアイテム一覧でマウス操作でスクロールバーを操作しアイテム一覧をスクロールする事が出来ました。

しかしボタンの選択をキーボードやゲームコントローラーで操作した時はスクロールバーを選択してスクロールしない限りはアイテム一覧をスクロール出来ませんでした。

そこで今回はキーボードやゲームコントローラーで選択するボタンを変更した時にアイテム一覧をスクロール出来るようにしたいと思います。

ただその機能を取り付ける場合はマウスでのスクロールが出来なくなります。(^_^;)

出来ないというよりはキーボードとゲームコントローラーによる操作とマウスでの操作を混在させて処理するのが大変なのでスクロールバーを直接操作出来なくしたといった方が正しいです。

両方の操作に対応したい!という方は色々試行錯誤してみてください。

現時点ではゲームコントローラーとキーボードでの操作に限定しておきます。

スポンサーリンク
スポンサーリンク

ItemPanel子要素のScrollbarをマウスで操作させない

まずはアイテム一覧(ItemPanel)のスクロールバーをマウスで操作出来ないようにします。

ItemPanel子要素のScrollbarを選択しScrollbarコンポーネントのinteractableのチェックを外します。

ユニティちゃんRPGのアイテム一覧のスクロールバーをマウスで操作出来ないようにする

これでアイテム一覧のスクロールバーをマウス操作出来なくなりました。

特定のアイテムを選択、選択解除した時の処理を追加

前回、アイテム一覧で見えるアイテムの種類は14個までにしました。

そこでキーボードやゲームコントローラーで15、16個目のアイテムパネルボタンを選択した時にItenPanel子要素のContentを移動し、15、16個目のアイテムパネルボタンがMaskの上の部分に来るように移動させます。

Assets/RPG/Scriptsに新しくItemPanelScrollScriptというスクリプトを作成します。

ItemPanelScrollScriptクラスはMonoBehaviourクラス、ISelectHandlerインタフェースとIDeselectHandlerインタフェースを継承して作成します。

インタフェースは作成するべきメソッドが宣言されているだけのものでISelectHandlerインタフェースはOnSelectメソッド、IDeselectHandlerインタフェースはOnDeselectメソッドを定義する必要があります。

contentはItemPanel子要素のContent、scrollbarにはItemPanel子要素のScrollbarを取得し設定します。

changeScrollValueは現在スクロールバーがスクロール中かどうか、destinationValueはスクロールの目的地、scrollSpeedはスクロールのスピード、scrollValueは1回でスクロールする値です。

Awakeメソッドではcontentとscrollbarを階層を辿って取得しています。

UpdateメソッドではchangeScrollValueがfalseの時(スクロール中でない)はその後の処理を実行しません。

スクロール中の時はcontentのローカル位置にMathf.MoveTowardsを使って現在の値から目的の値へと徐々に変化させた値を設定します。

Mathf.Absで現在のY軸の位置と目的地の引き算の絶対値を求め、ある程度目的地に移動していたら現在の位置を目的地に設定し、スクロールを終えてます。

OnSelectはこのスクリプトが取り付けられたゲームオブジェクトが選択された時に実行されるメソッドで、スクロール中であれば現在の位置に目的地を設定し、スクロールを終了します。

これはスクロール中にさらにアイテムパネルボタンを移動した時にすぐに目的地に設定し、次のスクロールに備える為です。

ボタンが選択された時にInput.GetAxis(“Vertical”)の値が0より小さい時(↓方向を押していた時)は目的地に現在のY軸の値にscrollValueを足した値を設定し、changeScrollValueをtrueにします。

↓方向を押していた時はそのアイテムパネルボタンがMaskの上に来るようにする為、Contentを上に移動させる必要があります。

Input.ResetInputAxes()で一旦入力をリセットしておきます。

そうしないと処理が連続して行われてしまう可能性があります。

OnDeselectメソッドはこのスクリプトが取り付けられたゲームオブジェクトの選択が解除された時に呼ばれます。

選択が解除される時はこのボタンを選択状態で↑方向の移動ボタンを押して、前のスクロール位置に戻る時です。

最初のスクロール位置に戻す為、Contentの目的地を下にする必要があります。

SetScrollValueメソッドはCommandScriptで設定したscrollValueとscrollSpeedの値を設定する為のメソッドです。

SetScrollValueメソッドはCommandScriptスクリプトから呼び出します。

CommandScriptでItemPanelScrollScriptの取り付け

アイテム一覧をスクロールする処理はItemPanelScrollScriptに記述しました。

ItemPanelScrollScriptは15、16個目のボタンが選択されたり、選択解除された時にContentのY軸を移動させる処理をしています。

なのでItemPanelButtonPrefabプレハブをインスタンス化した時、15、16個目のボタンだった時だけこのItemPanelScrollScriptを取り付けます。

CommandScriptスクリプトに処理を追加します。

まずはフィールドです。

scrollButtonNumは何個目のボタンからスクロールするかの指定で、数値は0から始まるので14を設定すると15、16個目のボタンからスクロールします。

scrollSpeedはスクロールするスピード、scrollValueはスクロールする数値、defaultScrollValueはデフォルトのスクロール値です。

ここで設定したscrollValueの値は調べる必要があり、そのやり方を記載します。

Unityを実行しアイテム一覧を表示したらContentゲームオブジェクトを選択し、15個目、16個目のアイテムが一番上に表示される位置にMove Toolを選択し、シーンビューのY軸の矢印をドラッグします。

ユニティちゃんRPGのItemPanel子要素のContentをMoveToolで移動させる

シーンビューでは以下のように15、16個目のアイテムパネルボタンが一番上に来るようにドラッグします。

ユニティちゃんRPGのContentをシーンビューでドラッグした状態

15、16個目のアイテムは『普通の剣』と『痺れ回復薬』となっており、ゲームビューで確認すると以下のように一番上に表示されるようにContentを移動させます。

ユニティちゃんRPGのContentをドラッグしゲームビューで確認した状態

移動させた状態でContentゲームオブジェクトのインスペクタのRect TransformのPos Yの値を確認し、これをCommandScriptのscrollValueに設定するようにします。

ユニティちゃんRPGのContentをドラッグした後のPos Yの値を調べる

scrollValueの値によってはスクロールする毎に徐々にアイテムパネルボタンの表示位置がずれてしまう可能性もあります。

アイテムパネルボタンの高さ、アイテムパネルボタン同士の隙間等を厳密に計算しscrollValueを設定した方がいいかもしれません。

Awakeメソッドに処理を追加します。

ゲームオブジェクト登場時のContentの位置をdefaultScrollValueに入れておきます。

CommandScriptのCreateItemPanelButtonメソッドに処理を追加します。

CreateItemPanelButtonメソッドが呼ばれたらContentの位置をdefaultScrollValueの位置に戻します。

これは最初にユニティちゃんのアイテムを表示した時にアイテム一覧をスクロールした状態で、大鳥ゆうじのアイテム一覧を表示するとスクロールしたままになってしまうので、毎回リセットをする為です。

itemPanelButtonNumは何個アイテムパネルボタンを作成したかの数を保持します。

持っているアイテム数分のitemPanelButtonPrefabをインスタンス化している処理で、インスタンス化したボタンが0番目、itemPanelButtonNumをscrollButtonNumで割って余りが0の時、scrollButtonNum + 1で割って余りが0の時にそのアイテムパネルボタンのインスタンスにItemPanelScrollScriptを取り付けます。

上ではItemPanelScrollScriptを取り付け、そのままSetScrollValueメソッドを呼び出し引数を渡しています。

引数では『名前付き引数』を使って何の値を渡しているかをわかりやすくしています(引数名と渡す引数のフィールド名が同じなので意味はないですが)。

アイテムパネル外をマウスで押した時の処理に追加

アイテムパネル以外をマウスで押すと選択がItemPanelの最初の子要素を強制的に選択させるという処理をアイテムコマンドを作成した時に取り付けましたが、今回のアイテムスクロールをした後にパネル外をマウスで押すとスクロールをした状態のまま最初のボタンが選択されるので、スクロール値も最初の位置に戻す処理を追加します。

CommandScriptのUpdateメソッド内の強制的にボタンを選択させる処理にItemPanelのスクロール値を初期位置に戻す処理を追加します。

currentCommandがCommandMode.ItemPanelの時に

を追加します。

これで機能が完成しました。

アイテム一覧をゲームコントローラーでスクロールしてみる

機能が出来たのでキーボードのキーかゲームコントローラーを使ってアイテム一覧がスクロールされるか確認してみましょう。

上のように15、16個目のボタンを選択、選択解除した時にアイテム一覧がスクロールするようになりました。

終わりに

これでアイテムコマンドが完成しました。

ただアイテムの選択をする時の移動が少し遅いですね。

というわけで次回はアイコンの移動(次のボタンの選択処理)が早くなるように設定を変更してみます。

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

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

コメント

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