コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】要素を使い回すスクロールを実装できる「Scroll - Mutate - Infinity - ZenUI」紹介

はじめに

「Scroll - Mutate - Infinity - ZenUI」を Unity プロジェクトに導入することで
要素を使い回すスクロールを実装できるようになります

目次

使用例

f:id:baba_s:20190414195004g:plain

特徴

  • スクロール内の要素がそれぞれ違う高さでも動作する
  • 要素の追加、挿入、削除ができる
  • 指定されたインデックスの要素にジャンプできる

基本的な使い方

スクリプトの作成

まずはスクリプトを作成します

public class ScrollItemData
{
    public string m_text;
}

スクロール内の要素の表示に使用するクラスを定義します

using Scrmizu;
using UnityEngine;
using UnityEngine.UI;

public sealed class ScrollItemUI : MonoBehaviour, IInfiniteScrollItem
{
    [SerializeField] private Text m_textUI = null;

    public void UpdateItemData( object target )
    {
        var data = target as ScrollItemData;
        gameObject.SetActive( true );
        m_textUI.text = data.m_text;
    }

    public void Hide()
    {
        gameObject.SetActive( false );
    }
}

スクロール内の要素を管理するコンポーネントを定義します

using Scrmizu;
using System.Linq;
using UnityEngine;

public class Example : MonoBehaviour
{
    [SerializeField] private InfiniteScrollRect m_scrollRectUI = null;

    private void Awake()
    {
        var list = Enumerable
            .Range( 0, 1000 )
            .Select( c => new ScrollItemData { m_text = ( c + 1 ).ToString() } )
            .ToArray()
        ;

        m_scrollRectUI.SetItemData( list );
    }
}

スクロールを制御するコンポーネントを用意します
これで、スクリプトの準備は完了です

シーンのオブジェクトの作成

次はシーンのオブジェクトを作成します

f:id:baba_s:20190414193555p:plain

基本的には ScrollRect と同じ構成で
スクロールビューのゲームオブジェクトを作ります
そして、ScrollRect の代わりに「Infinite Scroll Rect」をアタッチします

ScrollRect と違う点として、下記の項目を追加で設定する必要があります

項目 内容
Item Base スクロール内の要素として使用するゲームオブジェクト
Instantiated Item Count 使い回す数
Default Helght 要素の高さ(設定しなくても正常に動く?)
Interval 要素の配置間隔

f:id:baba_s:20190414194137p:plain

スクロールビューが作成できたらスクロール内の要素を表すオブジェクトを作成します
このオブジェクトには先ほど作成した「ScrollItemUI」コンポーネントをアタッチします
注意点として、RectTransform の Pivot などを上記の画像通りに
設定しておく必要があります

f:id:baba_s:20190414194149p:plain

最後に、先ほど作成した「Example」コンポーネントを
適当なオブジェクトにアタッチします
そして、「Scroll Rect UI」に「Scroll View」の参照を設定します

f:id:baba_s:20190414194719g:plain

以上で、要素を使い回すスクロールを実装できます

要素の追加、挿入、削除、指定した要素へジャンプ

private void OnGUI()
{
    // 要素を追加する
    if ( GUILayout.Button( "Add" ) )
    {
        var data = new ScrollItemData { m_text = "ピカチュウ" };
        m_scrollRectUI.AddItemData( data );
    }
    // 要素を挿入する
    if ( GUILayout.Button( "Insert" ) )
    {
        var data = new ScrollItemData { m_text = "ライチュウ" };
        m_scrollRectUI.InsertItemData( 0, data );
    }
    // 要素を削除する
    if ( GUILayout.Button( "Remove" ) )
    {
        m_scrollRectUI.RemoveAtItemData( 0 );
    }
    // 複数の要素を追加する
    if ( GUILayout.Button( "Add Range" ) )
    {
        var list = new []
        {
            new ScrollItemData { m_text = "フシギダネ" },
            new ScrollItemData { m_text = "フシギソウ" },
            new ScrollItemData { m_text = "フシギバナ" },
        };
        m_scrollRectUI.AddRangeItemData( list );
    }
    // 複数の要素を挿入する
    if ( GUILayout.Button( "Insert Range" ) )
    {
        var list = new []
        {
            new ScrollItemData { m_text = "ヒトカゲ" },
            new ScrollItemData { m_text = "リザード" },
            new ScrollItemData { m_text = "リザードン" },
        };
        m_scrollRectUI.InsertRangeItemData( 0, list );
    }
    // 複数の要素を削除する
    if ( GUILayout.Button( "Remove Range" ) )
    {
        m_scrollRectUI.RemoveRangeItemData( 0, 5 );
    }
    // すべての要素を削除する
    if ( GUILayout.Button( "Clear" ) )
    {
        m_scrollRectUI.ClearItemData();
    }
    // 指定した要素へジャンプする
    if ( GUILayout.Button( "Move Position" ) )
    {
        m_scrollRectUI.MovePositionAt( m_scrollRectUI.Count - 1 );
    }
}

InfiniteScrollRect クラスに用意されている関数を使用することで
要素の追加、挿入、削除、指定した要素へジャンプなどができます