軽くて高機能なUnityの大人気スクロールビューアセット、EnhancedScroller。
機能も性能も素晴らしいですが、ポンと置いてすぐ使える訳ではなく前準備が結構面倒くさいので、使い方を基礎から応用まで詳しく解説していきます。
EnhancedScrollerの公式サンプルを参考に記事を書いているので、実装は制作者の意図に100%沿ったものとなっているので安心してください。
僕が開発中のゲームではカテゴリー表示の部分とアイテムのサムネ一覧の2箇所で使い、カテゴリーを選ぶとアイテムのサムネがカテゴリーに合わせて切り替わるような、2つのリストが連動する形で利用しています。
これからEnhancedScrollerを導入したいという方もこの記事で雰囲気を掴んでみてください。
一列テキストリストの実装
一番シンプルな、テキストを表示する1列リストの実装方法を解説します。
表示部分の実装
まずはリストの表示部分を実装します。
HierarchyにUI > Canvasを追加して、子オブジェクトとして空のGameObjectを作ったら「Scroller」とリネームしておきます。
Scrollerを選択したら、Add Componentを押して
- Enhanced Scroller
- Image
- Mask
を追加します。
Scroll RectとCanvas Rendereは自動的に一緒に追加されます。
次に、Scrollerに子オブジェクトとして、空のGameObjectを追加します。
実行時、EnhancedScrollerが自動的に削除するので、名前はデフォルトのGameObjectのままで。
このGameObjectに子オブジェクトとして、UI > Panelを追加して「CellView」とリネームしておきます。
これがリストを表示するCell(要素)のテンプレートとなります。
CellViewの子オブジェクトとしてさらに、UI > Textを追加し、「Text」とリネームして、Anchorは縦も横もstretch、Alignmentは横をCenter、縦をMiddleとしておきます。
最後に、最初に追加したScrollerを選択して、Inspectorに表示されるScroll Rectの「Content」に、GameObjectをセットします。
以上でView部分の準備は完了です。
スクリプトの実装
表示部分にデータを流し込むコントローラとスクリプトを実装します。
空のGameObjectを作って、ScrollerControllerと名前をつけ、オブジェクトと同名のスクリプトを追加しておきます。
次に、前項で作成したCellViewに、同名のスクリプトを追加します。
最後に「ScrollerData」というデータクラスを1つ作成して前準備は完了です。コードを実装していきましょう。
ScrollerData
using UnityEngine;
public class ScrollerData : MonoBehaviour
{
public string cellText;
}
CellView
using TMPro;
using EnhancedUI.EnhancedScroller;
// EnhancedScrollerCellViewを継承している点に注意!
public class CellView : EnhancedScrollerCellView
{
// CellViewの子オブジェクトのTextをリンクする
public TextMeshProUGUI text;
public void SetData(ScrollerData data)
{
text.text = data.cellText;
}
}
ScrollerController
using UnityEngine;
using System.Collections.Generic;
using EnhancedUI.EnhancedScroller;
// IEnhancedScrollerDelegateインタフェースを継承していることに注意!
public class ScrollerController : MonoBehaviour, IEnhancedScrollerDelegate
{
private List<ScrollerData> _data;
public EnhancedScroller myScroller;
public CellView cellViewPrefab;
void Start()
{
_data = new List<ScrollerData>()
{
new ScrollerData() { cellText = "Lion" },
new ScrollerData() { cellText = "Bear" },
new ScrollerData() { cellText = "Eagle" },
new ScrollerData() { cellText = "Dolphin" },
new ScrollerData() { cellText = "Ant" },
new ScrollerData() { cellText = "Cat" },
new ScrollerData() { cellText = "Sparrow" },
new ScrollerData() { cellText = "Dog" },
new ScrollerData() { cellText = "Spider" },
new ScrollerData() { cellText = "Elephant" },
};
myScroller.Delegate = this;
myScroller.ReloadData();
}
public int GetNumberOfCells(EnhancedScroller scroller)
{
return _data.Count;
}
public float GetCellViewSize(EnhancedScroller scroller, int dataIndex)
{
return 100f;
}
public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex)
{
CellView cell = scroller.GetCellView(cellViewPrefab) as CellView;
cell.SetData(_data[dataIndex]);
return cell;
}
}
オブジェクトをリンク
ソースの実装が完了したら、各スクリプトのpublicフィールドにHierarchyのオブジェクトをリンクしていきます。
CellViewのリンク
CellViewを選択して、InspectorのCellViewスクリプトのTextに、CellViewの子オブジェクト、Textをリンクします。
ScrollerControllerのリンク
ScrollerControllerのリンクの前準備として、CellViewをProjectフォルダにドラッグ&ドロップをして、CellViewのPrefabを作成しておきます。
そして、ScrollerControllerを選択したら、Cell View Prefab欄には、今作成したCellViewPrefabを、My Scroller欄には、Canvas直下のScrollerをそれぞれリンクさせます。
最後に、Scrollerオブジェクトを表示したい好きなサイズに変えて実行すると、リストが表示されます。
何も表示されない場合は次をチェック
- フォントカラーが白になってないか?
- フォントが「LiberationSans SDF」じゃないか?何故かLiberationSans SDFだと何も表示されないです。
一列画像リストの実装
前項ではテキストを表示する1列リストの実装方法を解説しましたが、次に画像を表示する1列リストの例を紹介します。
基本的にはテキストのリストと同じなのですが差分だけ解説しても分かりづらいので、全部解説します。
表示部分の実装
まずはリストの表示部分を実装します。
HierarchyにUI > Canvasを追加して、子オブジェクトとして空のGameObjectを作ったら「Scroller」とリネームしておきます。
Scrollerを選択したら、Add Componentを押して
- Enhanced Scroller
- Image
- Mask
を追加します。
Scroll RectとCanvas Rendereは自動的に一緒に追加されます。
次に、Scrollerに子オブジェクトとして、空のGameObjectを追加します。
実行時、EnhancedScrollerが自動的に削除するので、名前はデフォルトのGameObjectのままで。
このGameObjectに子オブジェクトとして、UI > Panelを追加して「CellView」とリネームしておきます。
これがリストを表示するCell(要素)のテンプレートとなります。
CellViewの子オブジェクトとしてさらに、UI > Imageを追加します。
最後に、最初に追加したScrollerを選択して、Inspectorに表示されるScroll Rectの「Content」に、GameObjectをセットします。
以上でView部分の準備は完了です。
スクリプトの実装
表示部分にデータを流し込むコントローラとスクリプトを実装します。
空のGameObjectを作って、ScrollerControllerと名前をつけ、オブジェクトと同名のスクリプトを追加しておきます。
次に、前項で作成したCellViewに、同名のスクリプトを追加します。
最後に「ScrollerData」というデータクラスを1つ作成して前準備は完了です。コードを実装していきましょう。
ScrollerData
using UnityEngine;
public class ScrollerData : MonoBehaviour
{
// 画像ファイル名
public string cellImage;
}
CellView
using EnhancedUI.EnhancedScroller;
using UnityEngine;
using UnityEngine.UI;
// EnhancedScrollerCellViewを継承している点に注意!
public class CellView : EnhancedScrollerCellView
{
// CellViewの子オブジェクトのImageをリンクする
public Image image;
public void SetData(ScrollerData data)
{
image.sprite = Resources.Load<Sprite>(data.cellImage);
}
}
ScrollerController
using UnityEngine;
using System.Collections.Generic;
using EnhancedUI.EnhancedScroller;
// IEnhancedScrollerDelegateインタフェースを継承していることに注意!
public class ScrollerController : MonoBehaviour, IEnhancedScrollerDelegate
{
private List<ScrollerData> _data;
public EnhancedScroller myScroller;
public CellView cellViewPrefab;
void Start()
{
// Resourcesに置いた画像のファイル名一覧
_data = new List<ScrollerData>()
{
new ScrollerData() { cellImage = "top_1" },
new ScrollerData() { cellImage = "top_2" },
new ScrollerData() { cellImage = "top_3" },
new ScrollerData() { cellImage = "top_4" },
new ScrollerData() { cellImage = "top_5" },
new ScrollerData() { cellImage = "top_6" },
new ScrollerData() { cellImage = "top_7" },
new ScrollerData() { cellImage = "top_8" },
new ScrollerData() { cellImage = "top_9" },
new ScrollerData() { cellImage = "top_10" },
};
myScroller.Delegate = this;
myScroller.ReloadData();
}
public int GetNumberOfCells(EnhancedScroller scroller)
{
return _data.Count;
}
public float GetCellViewSize(EnhancedScroller scroller, int dataIndex)
{
return 100f;
}
public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex)
{
CellView cell = scroller.GetCellView(cellViewPrefab) as CellView;
cell.SetData(_data[dataIndex]);
return cell;
}
}
オブジェクトをリンク
ソースの実装が完了したら、各スクリプトのpublicフィールドにHierarchyのオブジェクトをリンクしていきます。
CellViewのリンク
CellViewを選択して、InspectorのCellViewスクリプトのImageに、CellViewの子オブジェクト、Imageをリンクします。
ScrollerControllerのリンク
ScrollerControllerのリンクの前準備として、CellViewをProjectフォルダにドラッグ&ドロップをして、CellViewのPrefabを作成しておきます。
そして、ScrollerControllerを選択したら、Cell View Prefab欄には、今作成したCellViewPrefabを、My Scroller欄には、Canvas直下のScrollerをそれぞれリンクさせます。
最後に、Scrollerオブジェクトを表示したい好きなサイズに変え、Assets/Resourcesフォルダーに画像を配置してから実行すると、リストが表示されます。
クリックイベントの実装
前項の画像リストをベースに、リストの項目をクリックしたら、リストの下に選択した画像を表示するサンプルを実装します。
実際の処理をScrollerContorllerに集めているのが大事なポイントです。
クリック部分の実装以外は前項を参照してください。
プレビューImageの作成
選択されたリストと同じ画像を表示するプレビューImageを追加しておきます。
CellView.csにクリック関連処理を追加
Cellがクリックされた時に実行したい処理内容を外部からセットしてもらうためにdelegateを追加します。
Cellがクリックされた時に呼ばれる関数OnSelectedも追加します。
Cellがクリックされた時に処理を実行する外部のクラスに、何番目のデータが選ばれたのかを教えたいので、 int indexの変数も追加しておきます。
using EnhancedUI.EnhancedScroller;
using UnityEngine;
using UnityEngine.UI;
public class CellView : EnhancedScrollerCellView
{
// 変数indexを追加
public int index;
public Image image;
// デリゲートを追加
public delegate void SelectedDelegate(EnhancedScrollerCellView cellView);
public SelectedDelegate selected;
// CellViewを選択した時の処理を追加
public void OnSelected()
{
if (selected != null) selected(this);
}
// 引数にindexを追加
public void SetData(int index, ScrollerData data)
{
this.index = index;
image.sprite = Resources.Load<Sprite>(data.cellImage);
}
}
CellViewにButtonを追加
CellViewが押された、という処理をするためにUI > Buttonを追加して、先程CellView.csに追加したOnSelectedをセットします。
その後、CellViewはprefabなので、Overridesボタンを押して出てくるメニューの「Apply All」を押してprefab内容の変更を反映させます。
これをしないとCellViewに一切の変更が反映されないので注意してください!
ScrollerController.csにクリック関連処理を追加
ScrollerController.csに、選ばれたCellViewの画像を表示させるプレビューImageと、CellViewが選択された時に実行させる内容を、ScrollerControllerに移譲する処理を追加します。
cell.SetDataでデータのindexを渡すように変更されている点も注意してください。
長いので追加した部分だけ共有します。
// 選ばれたCellViewの画像を表示させるプレビュー画像
public Image previewImage;
......
// CellViewがクリックされた時にCellViewから呼ばれる
private void CellViewSelected(EnhancedScrollerCellView cellView)
{
if (previewImage != null && cellView != null)
{
int index = (cellView as CellView).index;
previewImage.sprite = Resources.Load<Sprite>(_data[index].cellImage);
}
}
public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex)
{
CellView cell = scroller.GetCellView(cellViewPrefab) as CellView;
// 選ばれたデータのindexを第一引数で渡すように変更
cell.SetData(dataIndex, _data[dataIndex]);
// cellがクリックされた時に呼ばれる処理をセットする
cell.selected = CellViewSelected;
return cell;
}
ScrollerControllerにプレビューImageをセット
最後に、ScrollerControllerにプレビュー用のImageをセットして完成です。
実行してリストを選択すると、リスト下のプレビューエリアに選ばれた画像が表示されます。
複数列(グリッド)画像リストの実装
画像を複数列表示するリスト、今回は5列リストの例を紹介します。
表示部分の実装
まずはリストの表示部分を実装します。
HierarchyにUI > Canvasを追加して、子オブジェクトとして空のGameObjectを作ったら「Scroller」とリネームしておきます。
Scrollerを選択したら、Add Componentを押して
- Enhanced Scroller
- Image
- Mask
を追加します。
Scroll RectとCanvas Rendereは自動的に一緒に追加されます。
次に、Scrollerに子オブジェクトとして、空のGameObjectを追加します。
実行時、EnhancedScrollerが自動的に削除するので、名前はデフォルトのGameObjectのままで。
このGameObjectに子オブジェクトとして、UI > Panelを追加して「CellView」とリネームしておきます。
これがリストを表示するCell(要素)のテンプレートとなります。
CellViewの中に複数の画像を手間を掛けず綺麗に並べたいのでHorizontal Layout Groupを追加して、子要素が自動でリサイズされるようにControl Child Sizeにチェックを入れておきます。
そしてCellViewの子オブジェクトとして、UI > Imageを5つ追加します。
最後に、最初に追加したScrollerを選択して、Inspectorに表示されるScroll Rectの「Content」に、GameObjectをセットします。
以上でView部分の準備は完了です。
スクリプトの実装
表示部分にデータを流し込むコントローラとスクリプトを実装します。
空のGameObjectを作って、ScrollerControllerと名前をつけ、オブジェクトと同名のスクリプトを追加しておきます。
次に、前項で作成したCellViewに、同名のスクリプトを追加します。
最後に「ScrollerData」というデータクラスを1つ作成して前準備は完了です。コードを実装していきましょう。
ScrollerData
using UnityEngine;
public class ScrollerData : MonoBehaviour
{
// 画像ファイル名
public string cellImage;
}
CellView
using EnhancedUI.EnhancedScroller;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CellView : EnhancedScrollerCellView
{
// 複数のImageをインスペクターからここにセットする
public Image[] images;
public void SetData(int startingIndex, List<ScrollerData> data)
{
for (int i=0; i<images.Length; i++)
{
// 用意したデータを超えた場合は、no_image画像を表示する
string imageName = (startingIndex + i < data.Count) ? data[startingIndex + i].cellImage : "no_image";
images[i].sprite = Resources.Load<Sprite>(imageName);
}
}
}
ScrollerController
using UnityEngine;
using System.Collections.Generic;
using EnhancedUI.EnhancedScroller;
public class ScrollerController : MonoBehaviour, IEnhancedScrollerDelegate
{
private List<ScrollerData> _data;
public EnhancedScroller myScroller;
public CellView cellViewPrefab;
// 1列に何個の画像を表示するのか
int numberOfCellPerRow = 5;
void Start()
{
_data = new List<ScrollerData>()
{
new ScrollerData() { cellImage = "top_1" },
new ScrollerData() { cellImage = "top_2" },
new ScrollerData() { cellImage = "top_3" },
new ScrollerData() { cellImage = "top_4" },
new ScrollerData() { cellImage = "top_5" },
new ScrollerData() { cellImage = "top_6" },
new ScrollerData() { cellImage = "top_7" },
new ScrollerData() { cellImage = "top_8" },
new ScrollerData() { cellImage = "top_9" },
new ScrollerData() { cellImage = "top_10" },
new ScrollerData() { cellImage = "top_11" },
new ScrollerData() { cellImage = "top_12" },
};
myScroller.Delegate = this;
myScroller.ReloadData();
}
public int GetNumberOfCells(EnhancedScroller scroller)
{
// 1列にnumberOfCellPerRow個表示するので、行数はnumberOfCellPerRowで割る
return (_data.Count / numberOfCellPerRow) + 1;
}
public float GetCellViewSize(EnhancedScroller scroller, int dataIndex)
{
return 100f;
}
public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex)
{
CellView cell = scroller.GetCellView(cellViewPrefab) as CellView;
// 1行のnumberOfCellPerRow個画像があるので、numberOfCellPerRow個飛ばしで表示する
cell.SetData(cellIndex * numberOfCellPerRow, _data);
return cell;
}
}
オブジェクトをリンク
ソースの実装が完了したら、各スクリプトのpublicフィールドにHierarchyのオブジェクトをリンクしていきます。
CellViewのリンク
CellViewを選択して、InspectorのCellViewスクリプトのImagesに、CellViewの子オブジェクト、Imageを全部リンクします。
ScrollerControllerのリンク
ScrollerControllerのリンクの前準備として、CellViewをProjectフォルダにドラッグ&ドロップをして、CellViewのPrefabを作成しておきます。
そして、ScrollerControllerを選択したら、Cell View Prefab欄には、今作成したCellViewのPrefabを、My Scroller欄には、Canvas直下のScrollerをそれぞれリンクさせます。
最後に、Scrollerオブジェクトを表示したい好きなサイズに変え、Assets/Resourcesフォルダーに画像を配置してから実行すると、リストが表示されます。
<iframe style=”width: 600px; height: 130px; border: 0px;” src=”https://assetstore.unity.com/linkmaker/embed/package/36378/widget-wide”></iframe>