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

記事内に広告が含まれています。

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

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

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

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

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

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

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

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

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

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

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

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

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

2020/07/17にスクロール機能を全面的に変更しました。

スポンサーリンク

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

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

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

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

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

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

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

そこでキーボードやゲームコントローラーで13、14個目のアイテムパネルボタンを選択した時にItemPanel子要素のContentを下にスクロールし、

15、16個目のアイテムパネルボタンを選択した時にContentを上にスクロールするようにします。

Assets/RPG/Scriptsに新しくScrollManagerというスクリプトを作成し、ItemPanelの子要素にあるContentに取り付けます。

contentは自身のTransformを取得し設定します。

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

PreSelectedButtonプロパティは前に選択していたアイテムパネルボタンを入れておく為に用意しました。

AwakeメソッドではcontentとdefaultScrollValueを設定しています。

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

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

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

ScrollDownメソッドはアイテムパネルボタンに取り付けたスクリプトから呼び出し、スクロール中であれば現在の位置に目的地を設定し、スクロールを終了します。

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

ScrollManager.PreSelectedButtonがnullでなく引数で受け取ったアイテムパネルボタンが前に選択していたボタンよりYの位置が大きい時(現在のボタンが前に選択していたボタンより上にある時)にContentのYの位置をscrollValue分引きます。

ScrollUpメソッドはScrollDownの逆で現在のボタンが前に選択していたボタンより下にある時にContentのYの位置をscrollValue分足します。

Resetメソッドはアイテムパネル外をマウスで押した時等の初期化をする時に呼び出し、前に選択していたボタンのリセットとスクロールのリセットを行います。

ここで設定した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を設定した方がいいかもしれません。

ボタンに取り付けるスクリプトの作成

ScrollManagerスクリプトでアイテム一覧のスクロールをしますが、その処理を呼び出すスクリプトを作成します。

Assets/RPG/Scriptsフォルダに新しくScrollDownScriptとScrollUpScriptを作成します。

どちらのスクリプトもCommandScript内から該当するボタンに取り付けます。

ScrollDownScriptはMonoBehaviour、ISelectHandler、IDeselectHandlerを継承して作成し、ボタンを選択した時、ボタンの選択を解除した時の処理を実装します。

ScrollDownScriptはScrollManagerスクリプトを自身の親の階層から探して取得します。

OnSelectメソッドはボタンが選択された時に呼び出されるので、そこでScrollManagerのScrollDownメソッドを自身のTransformを渡して呼び出します。

またScrollManager.PreSelectedButtonに自身のゲームオブジェクトを設定し前に選択していたボタンに自身を設定します。

ボタン選択解除時の処理は今回何もしていませんが、何か必要なことがあるかもしれないので作っています。

ScrollUpScriptスクリプトはScrollDownScriptとほぼ同じでScrollUpメソッドを呼び出す処理に変えています。

CommandScriptでScrollDownScriptとScrollUpScriptの取り付け

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

アイテム一覧をスクロールさせる為に一画面の最後のボタン二つにScrollDownScriptを取り付け、スクロール後の最初のボタン二つにScrollUpScriptを取り付ける必要があります。

なのでItemPanelButtonPrefabプレハブをインスタンス化した時、12、13個目のボタンだった時にScrollDownScript、14、15個目のボタンだった時にScrollUpScriptを取り付けます。

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

まずはフィールドです。

scrollDownButtonNumは何個目のボタンからスクロールするかの指定で、数値は0から始まるので12を設定すると12、13個目のボタンが選択された時にContentを下にスクロールします。

scrollUpButtonNumも同じでこちらの場合は14、15個目のボタンが選択された時にContentを上にスクロールします。

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

contentを取得した後に処理を追加し、contentに取り付けたScrollManagerスクリプトを取得します。

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

CreateItemPanelButtonメソッドが呼ばれたらScrollManagerのResetメソッドを呼んでリセットします。

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

itemPanelButtonNumは1画面中でアイテムパネルボタンの番号を保持します。

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

AddComponentで該当するコンポーネントをゲームオブジェクトに取り付けることが出来ます。

ScrollUpScriptを取り付ける処理も同じように行います。

itemPanelButtonNumをインクリメントした後にitemPanelButtonNumの値を変更する処理を追加します。

スクリプトを取り付けるアイテムパネルボタンの番号を変更し、スクロールした後のボタンも同じようにスクリプトを取り付けられるようにします。

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

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

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

currentCommandがCommandMode.ItemPanelの時に

を追加します。

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

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

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

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

終わりに

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

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

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

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

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

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