公開日:2017年11月16日
更新日:2017年12月04日
使用Unity Version:2017.2.0f3
UnityのUIには「Scroll View」があり、簡単にリスト表示を実現することができます。
リストには、Scriptから動的にUI(Panel, Text, Imageなど)を追加できます。手順としては、項目のPrefabを作成し、それをリストに追加します。
1. 項目のPrefab作成
今回は編集用のSceneを別につくり、そのSceneで以下のPanelを作成し、Prefabにしました。
2. Scroll Viewの作成とコンポーネントの追加
リスト表示を行うSceneで、Canavs、Panel、Scroll Viewを追加します。PanelとScroll Viewはフルサイズ表示に設定しています。
今回は縦スクロール(Vertical)のみを使うので、不要な横スクロール(Horizontal)を削除します。
次に「Scroll View → Viewport → Content」に2つのコンポーネントを追加します。
- Component Size Filter
- Vertical Layout Group
「Component Size Filter → Vertical Fit」をPreferred Sizeに、「Vertical Layout Group→Child Controls Size → Width」をチェックありに設定します。
3. Scriptの作成
リストに項目を追加するScriptを作成し、コンポーネントとしてCanvasに追加します。
[ScrollViewController.cs] using UnityEngine; using UnityEngine.UI; public class ScrollViewController : MonoBehaviour { public RectTransform prefab; void Start() { Transform content = transform.Find("Panel/Scroll View/Viewport/Content"); for (int i = 0; i < 30; i++) { RectTransform node = Instantiate(prefab) as RectTransform; node.Find("LeftText").GetComponent<Text>().text += i; node.Find("CenterText").GetComponent<Text>().text += i; node.Find("RightText").GetComponent<Text>().text += i; node.SetParent(content); } } }
最後にPrefab化したPanelを、Scriptで定義した変数prefabに設定します。
再生すると、リスト表示が確認できます。
と、開発時は、ここまで順調だったのですが、「Scale With Screen Size」を設定したときに予期せぬことが起こりました。「Scale With Screen Size」については、以下の投稿を参照して下さい。
4. Scale With Screen Size対応
「Canvas → Canvas Scaler」を以下のように設定します。
- UI Scale Modeを「Scale With Screen Size」
- Reference ResolutionのXを720、Yを1280
- Screen Match Modeを「Expand」
このときスクリーンサイズを「Protrait 720 x 1280」で再生すると、当然普通に表示されます。ですが、スクリーンサイズを「Portrait 1080 x 1920」で再生すると、項目のPanelが縮小されてしまいます。というより「Portrait 720 x 1280」のサイズのままです。
「Portrait 1080×1920」で再生したときの項目のPanelのScaleを見ると「0.666…」となっています。「1280/1920 = 0.666…」ですから、多分「Portrait 720×1280」のサイズに合わせて縮小されているのだと思います。
なので、Scaleを「0.666…から1」に変更すれば、対応できそうです。
PanelのlocalScaleを1にする処理を、Scriptに追加します。
[ScrollViewController.cs] public class ScrollViewController : MonoBehaviour { public RectTransform prefab; void Start() { // 2017-12-04修正 Vector3.one = Vector3(1,1,1)が定義されていた // 1のScaleを作成 // Vector3 nodeScale = new Vector3(1.0f, 1.0f, 1.0f); RectTransform content = transform.Find("Panel/Scroll View/Viewport/Content"); for (int i = 0; i < 30; i++) { RectTransform node = Instantiate(prefab) as RectTransform; node.Find("LeftText").GetComponent<Text>().text += i; node.Find("CenterText").GetComponent<Text>().text += i; node.Find("RightText").GetComponent<Text>().text += i; node.SetParent(content); // リストに追加してからScale修正 node.localScale = Vecotr3.one; } } }
「Portrait 1080 x 1920」で再生すると。。。
うまくいきましたね。
今回はScript内でScaleを変更しましたが、可能ならコンポーネントの設定で対応したほうがスマートです。
もし、コンポーネントの設定で対応する方法をご存知の方がいましたらコメント下さい。
よろしくお願いします。