【Unity】「FancyScrollView」を公開しました

高度に柔軟なアニメーションを実装できる汎用のScrollViewコンポーネントです。 無限スクロールも対応しています。
github.com

f:id:setchi_q:20171019193047p:plain
f:id:setchi_q:20170226144706g:plain
f:id:setchi_q:20170226144523g:plain

以下ほぼ README のコピペです

導入

Unity 2017.1.0 (C# 6.0) 以降が必要です。このリポジトリを Clone するか、 Asset Store からプロジェクトにインポートしてください。

サンプル

FancyScrollView/Examples/Scenes/ を参照してください。

サンプル名 説明
01_Basic 最もシンプルな構成の実装例です。
02_CellEventHandling セルからのイベントをハンドリングする実装例です。
03_InfiniteScroll 無限スクロールの実装例です。
04_FocusOn ボタンで左右のセルにフォーカスする実装例です。

仕組み

FancyScrollView はセルの位置を更新する際に、画面に見える範囲を正規化した値を各セルに渡します。セル側では 0.0 ~ 1.0 の値をもとにスクロール中の見た目を自由に制御できます。

使い方

もっともシンプルな構成では、

  • セルにデータを渡すためのオブジェクト
  • セル
  • スクロールビュー

の実装が必要です。

スクリプトの実装

セルにデータを渡すためのオブジェクトを定義します。

public class ItemData
{
    public string Message;
}

FancyScrollViewCell を継承して自分のセルを実装します。

using UnityEngine;
using UnityEngine.UI;
using FancyScrollView;

public class MyScrollViewCell : FancyScrollViewCell<ItemData>
{
    [SerializeField] Text message;

    public override void UpdateContent(ItemData itemData)
    {
        message.text = itemData.Message;
    }

    public override void UpdatePosition(float position)
    {
        // position は 0.0 ~ 1.0 の値です
        // position に基づいてスクロールの外観を自由に制御できます
    }
}

FancyScrollView を継承して自分のスクロールビューを実装します。

using UnityEngine;
using System.Linq;
using FancyScrollView;

public class MyScrollView : FancyScrollView<ItemData>
{
    [SerializeField] Scroller scroller;
    [SerializeField] GameObject cellPrefab;

    protected override GameObject CellPrefab => cellPrefab;

    void Start()
    {
        scroller.OnValueChanged(base.UpdatePosition);
    }

    public void UpdateData(IList<ItemData> items)
    {
        base.UpdateContents(items);
        scroller.SetTotalCount(items.Count);
    }
}

スクロールビューにデータを流し込みます。

using UnityEngine;
using System.Linq;

public class EntryPoint : MonoBehaviour
{
    [SerializeField] MyScrollView myScrollView;

    void Start()
    {
        var items = Enumerable.Range(0, 50)
            .Select(i => new ItemData {Message = $"Cell {i}"})
            .ToArray();

        myScrollView.UpdateData(items);
    }
}

インスペクタ上の設定

My Scroll View
プロパティ 説明
Cell Spacing セル同士の間隔を float.Epsilon ~ 1.0 の間で指定します。
Scroll Offset スクロールのオフセットを指定します。例えば 0.5 を指定してスクロール位置が 0 の場合、最初のセルの位置が 0.5 になります。
Loop オンにすると、セルをループして配置します。無限スクロールさせたい場合はオンにします。
Cell Prefab セルの Prefab を指定します。
Cell Container セルの親要素となる Transform を指定します。
Scroller
プロパティ 説明
Viewport ビューポートとなる RectTransform を指定します。ここで指定された RectTransform の範囲内でジェスチャーの検出を行います。
Direction Of Recognize ジェスチャーを認識する方向を Vertical か Horizontal で指定します。
Movement Type コンテンツがスクロール範囲を越えて移動するときに使用する挙動を指定します。
Scroll Sensitivity スクロールの感度を指定します。
Inertia 慣性のオン/オフを指定します。
Deceleration Rate Inertia がオンの場合のみ有効です。減速率を指定します。
Snap - Enable Snap を有効にする場合オンにします。
Snap - Velocity Threshold Snap がはじまる閾値となる速度を指定します。
Snap - Duration Snap 時の移動時間を秒数で指定します。
Data Count アイテムのデータ件数の総数です。基本的にスクリプトから設定します。

Q&A

データ件数が多くてもパフォーマンスは大丈夫?

表示に必要なセル数のみが生成されるため、データ件数がパフォーマンスに与える影響はわずかです。セル間のスペース(同時に存在するセルの数)とセルの演出は、データ件数よりもパフォーマンスに大きな影響を与えます。

自分でスクロール位置を制御したいんだけど?

FancyScrollView の次の API を使用してスクロール位置を更新できます。

protected void UpdatePosition(float position)

サンプルで使われている Scroller を使う場合は、次の API を使用して FancyScrollView のスクロール位置を更新できます。

public void ScrollTo(int index, float duration)
public void JumpTo(int index)
public void OnValueChanged(Action<float> callback)

Scroller を使わずにあなた自身の実装で全く違った振る舞いをさせることもできます。

セルで発生したイベントを受け取れる?

セル内で発生したあらゆるイベントをハンドリングできます。 サンプルにセルで発生したイベントをハンドリングする実装が含まれていますので、参考にして実装してください。

セルをLoop(無限スクロール)させたいんだけど?

無限スクロールをサポートしています。実装手順は下記の通りです。

  • ScrollView の Loop をオンにするとセルが循環し、最初のセルの前に最後のセル、最後のセルの後に最初のセルが並ぶようになります。
  • サンプルで使用されている Scroller を使う場合は、「Movement Type」を「Unrestricted」にするとスクロール範囲が無制限になります。

実装例( FancyScrollView/Assets/FancyScrollView/Examples/03_InfiniteScroll at master · setchi/FancyScrollView · GitHub
)が含まれていますので、こちらも参考にしてください。


その他、不具合・要望があれば
setchi (@setchi) | Twitter
に連絡いただくか、プルリクをお願いします。