今回は、第14回と第16回で作成したリストを、メニュー画面(第13回)の中に組み込みます。
今回は思ったよりあっさり動きましたが、課題が残りました。
構成
これまでに作ったメニューの要素と関係性を以下にまとめます。
これまでの構成(修正前)
第14回、第16回で、単純なリストをScrollViewで作成しました。
また、第13回で、Submit を押したら次の画面を表示する単純なメニューをPanelで作成しました
(次の画面への参照だけを持つC#スクリプト Window.cs を付けてあります)。
Hierarchyウィンドウでは以下の関係になっています。
修正後
メニューの要素(ListItem、QueryUse)にリスト(ScrollView)をぶら下げます。
最初は、ScrollView (ScrollViewController) に、メニュー (Window) を 継承か実装させようと思いましたが、うまくいきませんでした。最終的に、ゲームオブジェクトの性質を使って親子関係にしたら、すんなりと動きました。
構成の変更
ScrollView の移動と複製
ScrollView を ListItem と QueryUse にぶら下げます。
(1) Hierarchyウィンドウで、ScrollView の行 を ListItem の行にドラッグ&ドロップ
(2) ScrollView の行を右クリック > Copy
(3) QueryUse の行を右クリック > Paste
この辺りは本当に直感的です。
コードの修正
Window
ScrollView の親ゲームオブジェクトになる ListItem と QueryUse (Window.csが付いている)を修正します。Window.cs に、ScrollView への参照と、ScrollView への Navigate() の伝達を追加します。(子オブジェクトの取得は第14回の補足2にまとめてあります)
Window.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Window : MonoBehaviour { // 次のウィンドウ [SerializeField] Window windowNext; private ScrollViewController child; // Start is called before the first frame update void Start() { child = gameObject.transform.GetChild(0).gameObject.GetComponent<ScrollViewController>(); } public void Navigate(Vector2 value) { if( child != null ){ child.Navigate(value); } } public void SetActive(bool b){ gameObject.SetActive(b); } public Window Next(){ // リスト要素毎にNextを持つ。その種類のWindowNextを返す。 // 今はwindowのテストのため、windowNextをそのまま返す return windowNext; } // Update is called once per frame void Update() { } }
Window の付いたゲームオブジェクトの Image を無効化
Window の付いたゲームオブジェクトには、もともと表示テスト用にImageが付いていたので、一旦無効化します。
(今後使いそうな気もするので、削除はせず、チェックだけを外します)
(1) Hierarchyウィンドウで、ListItem を選択
(2) Inspectorウィンドウで、Image の左のチェックボックスのチェックを外します。
※QueryUse も同じ。
動作テスト
以下を確認できました。
●最初のリストが表示されること
●最初のリストでSubmitを押した時に、次のリストが表示されること
●リストを持たない3番目のメニューの表示までを行えること
少し気持ちを盛り上げるために、適当にアイテム名を入れています。
そのうち、もう少しかっこよくしたいなぁ・・・
残課題
今回の方法では、いくつか不具合があることが分かりました。次回以降に修正します。
● リストを表示した時に、最初の1個目のアイテムが選択表示にならない(NullReferenceExceptionが出ている)
● 2つ目のリストが選択状態になった時に、1つ目のリストの選択状態が解除される(どれを選択していたか分からなくなる)
前回の判断で、EventSystemを使用したのですが、それは Deselect / Select イベントを発行したかったからでした。今回のように複数のリストを表示する場合は、前のリストの選択状態を保持できる仕組みが必要そうです。
→ 第21回の記事で、上記の不具合修正を行いました。
tomo-mana.hatenablog.com
次回やること
ステータスの作成とアイテムリストの作成
今回、分からなかったこと
今後の調査のために、以下を残しておこうと思います。
継承 (Extend) での失敗
継承での場合、親クラスで実装された子クラス側でもオーバーライドがうまくできませんでした。(Window を ScrollViewController に継承した時に、Navigate() のオーバーライドができません)
インターフェース (interface/Implement) での失敗
インターフェースでの場合、同じインターフェース型を返す関数型を実装できないようでした。
interface として定義できますが、実装した時に Less Accessible の警告が出て、コンパイルが通らないようでした。(Window を IWindowElement インタフェースとして定義した時に、IWindowElement Next() がインターフェースとしては作成できますが、ScrollViewController に実装した時にLess Accessibleエラーが表示されます)
→ 第19回の記事で、継承とインターフェースについて調べた内容をまとめました。
tomo-mana.hatenablog.com