Unityでお手軽にスクロール実装！Simple Scroll-Snapの紹介！

[PONOS Advent Calendar2022](https://qiita.com/advent-calendar/2022/ponos) の21日目の記事です。
昨日は@aibausoundさんの[Ruby on RailsでCloud Spannerエミュレータを使ってみる](https://qiita.com/aibausound/items/33b622b73d354f1d4e1e)でした。
# 初めに
ゲームを遊んでいると、よくスクロールというものを見かけると思います。
ステージやアイテム、キャラクター一覧など、上下や左右に指を動かして
リストを移動させているアレですね。

Unityでスクロールを実装しようとすると標準機能の「ScrollRect」を使うと思います。
最低限の機能はついていますが
「スナップ機能つけたいな...」
「特定のオブジェクトまで自動スクロールしてほしいなあ...」
「無限にスクロールできるようにしたいなあ...」
なんて考えたことないでしょうか。
ScrollRect単体でも、できないことはないですが実装が大変だったりします。
また、Unity初心者の方だとスクロール機能の実装は大変だと思います。
簡単に実装したい！という方におすすめなのがSimple Scroll-Snapです！

# Simple Scroll-Snapの使い方！
## Asset StoreからSimple Scroll-SnapをダウンロードしてUnityにインポート
https://assetstore.unity.com/packages/tools/gui/simple-scroll-snap-140884?locale=ja-JP#description

## シーンに配置
インポートするとAssetsのところにSimpleScroll-Snapというフォルダが作られてる。
![スクリーンショット 2022-12-15 15.45.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909345/c716eb20-5587-b86c-fda1-49084bc9270a.png)
中にはいろいろ入っているが、まずはフォルダの中のPrefabsをクリックしてScroll-SnapというPrefabをシーンに配置してみよう。
配置すると実にシンプルなUIが登場。
中身は下記の通り。
![スクリーンショット 2022-12-19 10.55.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909345/38d796a4-71d9-c130-0eec-21af3516f4b0.png)
再生すると番号のついたImageが横にスクロールする動き。

Simple Scroll-Snapのいいところは、オブジェクト同士の間付近までスクロールすると自動的に近い方のオブジェクトが真ん中に来てくれるところですね。
ScrollRectにはない機能なので嬉しいですね。
（ScrollRectオンリーでもできなくはないですが、構築が大変だったりで結構しんどいのでありがたいですね）

## 無限スクロールのやり方。
やり方はとっても簡単。
![スクリーンショット 2022-12-15 19.06.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909345/38e02033-a0a4-aaf8-ba9c-26338069c19e.png)
インスペクター欄のUseInfiniteScrolllingにチェックを入れるだけ。
たったこれだけで無限にスクロールできるようになる。


## 指定したオブジェクトをスクロール欄に表示する方法
今は数字のついたImageを表示していますが、他のオブジェクトに差し替えたい場合は以下の２パターンで行える

- 非再生時にSceneで直接Contentにオブジェクトを入れる
- Script側でオブジェクト生成→Contentに入れる。

最初から表示する内容が決まっているなら前者のやり方でも問題ないですが、ステージやアイテムなど状況によって表示するものや数などは変わってくるのでコード側で制御する後者の方を推奨します。
ここではコード側でスクロールに追加するやり方を解説します。

まずはスクロールに表示するオブジェクトを用意します。
内容はなんでもいいので今回はオブジェクトごとに違う色が出るようにしています。
```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.UI;

public class TailObject : MonoBehaviour
{
    [SerializeField] Image tailImage = default;
    public void Initialize(Color tailColor)
    {
        tailImage.color = tailColor;
    }
}
```
次に先ほど用意したオブジェクトを生成、スクロールに追加するようにします。
```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//コード上でSimpleScrollSnapを扱えるようにする
using DanielLochner.Assets.SimpleScrollSnap;

public class Test : MonoBehaviour
{

    [SerializeField] SimpleScrollSnap scrollSnap = default;
    [SerializeField] TailObject originalTailObject = default;

    void Start()
    {
        Color[] colorList = { Color.black, Color.blue, Color.cyan, Color.gray, Color.green };

        for (int i = 0; i < 5; ++i)
        {
            TailObject tailObject = Instantiate(originalTailObject, scrollSnap.Content);

            int index = i;
            tailObject.Initialize(colorList[index]);
        }
    }

```
SimpleScrollSnapをコードで扱う際は
<b>using DanielLochner.Assets.SimpleScrollSnap;</b>
を読んでやる必要があります。
上記を呼ぶことによって
SimpleScrollSnapの変数を宣言できます。

生成したオブジェクトはInstantiateの引数にscrollSnap.Content
または、tailObject.gameObject.transform.parentでContentにしてContentの子オブジェクトに設定するとスクロールに追加してくれます。
また、後述するscrollSnap.AddToFrontやscrollSnap.AddToBackなどでもスクロールに追加できます。

# Simple Scroll-Snapの便利な関数紹介
最後にSimpleScrollSnapの便利な関数を紹介します。

## 移動関連
ボタンを押した際の表示の切り替え、特定のパネルに移動などタッチしてのスクロール以外にも動かしたい時に便利です。
### GoToNextPanel()
１つ次のパネルへ移動
### GoToPreviousPanel()
１つ前のパネルへ移動
### GoToPanel(int panelNumber)
指定した番号のパネルへ移動
## 追加関連
スクロールにオブジェクトを追加する際はInstantiateの引数でContentを使用するのが基本ですが
後から追加したい時もあるかと思います。その時はこちらを使いましょう。
### AddToBack(GameObject panel)
スクロールの最後にオブジェクト追加
### AddToFrontGameObject panel)
スクロールの最初にオブジェクト追加
### Add(GameObject panel,int index)
指定した番号のところにオブジェクト追加


# 最後に
一見地味に見えるかもしれないスクロールですが、ちょっと動きが変わるだけでもゲームの見え方は変わってくるのではと思います。
また、スクロール機能の実装が苦手な方もSimple Scroll-Snapを使用することで簡単にスクロール機能を追加することができます。
便利なのでおすすめです。

明日は@ackylaさんの記事になります！