アイテムの一覧、ステージ選択、ランキング・・・項目がたくさんあって画面に入りきらないときは、スクロールできるリストにします。今回はScroll Viewと、部品を自動できれいに並べてくれるLayout Groupを組み合わせて、アイテムリストを作ってみましょう!
この記事で学べること
- Scroll Viewの作り方と、中のしくみ
- Layout Group(Vertical / Horizontal / Grid)で自動で並べる方法
- Content Size Fitterで、中身に合わせて大きさを変える方法
- スクリプトからリストの項目を増やす方法
前提知識
- 入力系のUIを作ろう:InputField・Slider・Toggle・Dropdown
- スクリプトからプレハブを生成しよう:Instantiateの使い方
Scroll View(スクロールできる枠)
Scroll Viewを作る
- Canvasを右クリック>UI>Scroll View
- 四角い枠と、右と下にスクロールバーが表示される
Scroll Viewのしくみ
- Scroll View:全体。Scroll Rectコンポーネントでスクロールの動きを管理する
- Viewport:見える範囲の「窓」。この外にはみ出した部分は隠れる
- Content:スクロールする中身。リストの項目はContentの子に入れる
- Scrollbar Horizontal / Vertical:横と縦のスクロールバー
Contentが窓(Viewport)より大きいときだけ、スクロールできます。
縦だけにスクロールさせる
- Scroll RectのHorizontalのチェックを外す(横にはスクロールしない)
- 使わないScrollbar Horizontalは削除し、Scroll RectのHorizontal Scrollbarの欄が「None」になっていることを確認
- Scroll Sensitivity:マウスホイール1回でスクロールする量。初期値だと遅いと感じたら、大きくする
Layout Groupで自動で並べる
項目を1つずつ手で並べるのは大変です。Layout Groupを付けると、子の部品を自動できれいに並べてくれます。
| コンポーネント | 並べ方 |
|---|---|
| Vertical Layout Group | 縦に1列 |
| Horizontal Layout Group | 横に1列 |
| Grid Layout Group | マス目(タイル状) |
Vertical Layout Groupを付ける
- Contentを選び、Add Component>Layout>Vertical Layout Group
- Padding:まわりの余白
- Spacing:項目どうしのすき間
- Child Alignment:どこに寄せて並べるか(Upper Center:上・中央)
- Control Child Size / Child Force Expand:子の幅や高さを、Layout Groupがそろえるかどうか
- 縦に並べるリストなら、Widthにだけチェックを入れると、横幅がそろって高さは項目のままになります
子に置いたボタンのRect Transformの位置は、Layout Groupが決めるので手で動かせなくなります(Inspectorがグレーになります)。
Content Size Fitterで中身に合わせる
項目が増えたら、Contentの高さも自動で伸びてほしいですよね。そのためにContent Size Fitterを付けます。
- Contentに、Add Component>Layout>Content Size Fitter
- Vertical Fit:Preferred Sizeにする
これで、子の数に合わせてContentの高さが自動で変わり、はみ出した分がスクロールできるようになります。
項目の高さを決める
- リストに並べるボタンなどには、Add Component>Layout>Layout Elementを付ける
- Min Height(または Preferred Height)に高さ(例:60)を入れる
Layout Groupは、この値を見て項目の高さを決めます。
スクリプトでリストの項目を作る
アイテム名のリストから、ボタンを自動で並べてみましょう。
1. 項目のプレハブを作る
- Contentを右クリック>UI>Button – TextMeshProを作り、名前をItemRowにする
- ItemRowに、Add Component>Layout>Layout ElementでMin Heightを60にする
- 下の「ItemRow」スクリプトを作って、ItemRowにアタッチする
- ItemRowのInspectorで、Button欄に自分のButton、Label欄に子のText (TMP)を設定
- ItemRowをProjectウィンドウにドラッグしてプレハブにし、Hierarchyのほうは削除する(第7章の手順です)
using UnityEngine;
using UnityEngine.UI;
using TMPro;
// リストの1項目。自分のボタンが押されたら、自分のアイテム名をログに出す
public class ItemRow : MonoBehaviour
{
[SerializeField] private Button button;
[SerializeField] private TMP_Text label;
private string itemName;
void Awake()
{
button.onClick.AddListener(OnClicked);
}
void OnDestroy()
{
button.onClick.RemoveListener(OnClicked);
}
// 作ったあとに、表示する名前を設定する
public void Setup(string newItemName)
{
itemName = newItemName;
label.text = newItemName;
}
private void OnClicked()
{
Debug.Log("アイテムが選ばれた: " + itemName);
}
}
2. 項目を並べるスクリプト
「ItemList」という名前でスクリプトを作り、Scroll Viewにアタッチします。
using UnityEngine;
public class ItemList : MonoBehaviour
{
[SerializeField] private ItemRow itemRowPrefab; // 項目のプレハブ
[SerializeField] private Transform content; // Scroll ViewのContent
[SerializeField] private string[] itemNames =
{
"やくそう", "どくけしそう", "キメラのつばさ", "どうのつるぎ", "かわのたて",
"たびびとのふく", "せいすい", "まほうのせいすい", "ちからのたね", "すばやさのたね"
};
void Start()
{
foreach (string itemName in itemNames)
{
// Contentの子として、項目を作る
ItemRow row = Instantiate(itemRowPrefab, content);
row.Setup(itemName);
}
}
}
Instantiate(プレハブ, 親)で、Contentの子として項目を作ります。Layout Groupが自動で並べてくれるので、位置を指定する必要はありません- プレハブの変数を
ItemRow型にしておくと、作った直後にSetupを呼べます - ItemListのInspectorで、Item Row PrefabにプレハブのItemRow、ContentにScroll ViewのContentを設定します
再生して、10個のアイテムが縦に並び、スクロールできて、押すとConsoleに名前が出れば成功!
スライム項目を増やしたのに、スクロールできない・・・



ContentにContent Size Fitterが付いているか確認してみて!Contentの高さが伸びないと、窓より大きくならないからスクロールできないんだ
Grid Layout Groupでタイル状に並べる
アイテムのアイコンを並べるときなどは、Grid Layout Groupが便利です。
- Cell Size:1マスの大きさ
- Spacing:マスどうしのすき間
- Constraint:Fixed Column Count:1行に並べる数を決める(4なら4列)
VerticalをGridに付け替えるだけで、同じItemListのスクリプトでタイル状のリストになります(そのときは、ItemRowのLayout Elementの高さより、GridのCell Sizeが優先されます)。
よくあるエラーと対処法
エラー:スクロールできない
- 原因:Contentが窓(Viewport)より大きくなっていない
- 対処法:ContentにContent Size Fitter(Vertical Fit:Preferred Size)を付ける。項目にLayout Elementで高さを付ける
エラー:項目が重なって表示される・高さが0になる
- 原因:Layout GroupのControl Child SizeのHeightにチェックがあるのに、項目に高さの指定がない
- 対処法:項目にLayout ElementのMin Heightを設定する。またはControl Child SizeのHeightのチェックを外す
エラー:リストの外に項目がはみ出して見える
- 原因:ViewportのMask(はみ出しを隠すコンポーネント)が外れている
- 対処法:ViewportにMask(またはRect Mask 2D)が付いているか確認する
エラー:項目の位置が手で動かせない
- 原因:Layout Groupが位置を決めているため(正常な動き)
- 対処法:位置を変えたいときは、Layout GroupのPaddingやSpacing、Child Alignmentで調整する
まとめ
- Scroll View:Viewport(窓)の中のContent(中身)をスクロールさせる。項目はContentの子に入れる
- Layout Group:Vertical / Horizontal / Gridで、子を自動で並べる
- Content Size Fitter:中身に合わせてContentの大きさを変える
- Instantiate(プレハブ, content)で、スクリプトから項目を増やせる
これで第9章のUIはおしまいです!次の第10章では、作ったゲームをビルドして、ほかの人に遊んでもらえる形にしていきます。
コメント