UI
C#
Unity
ゲーム制作
ゲーム開発

【Unity】【C#】ScrollViewをスクロールさせるボタン(Button)を実装する

概要

RaycastTargetがtrueのGameObjectをScrollViewの中に置いたら通常のスクロールが上手く行かなかったため、スクロール用のボタンを用意してボタン長押しでスクロールするようにしました。

今回はその内容を共有します。

導入手順

1.Button用にImage4つをCanvas配下に置きます。名前は下記の通りにします。
LeftButton ※左へスクロールするボタン
RightButton ※右へスクロールするボタン
LeftestButton ※左端へ飛ぶボタン
RightestButton ※右端へ飛ぶボタン

2.ButtonにEventTriggerをアタッチして、「Add New EventType」からPointerUpとPointerDownを追加します。

3.ScrollView(以外でも大丈夫です)にScrollViewCtr.csをアタッチして、Buttonの種類に応じて2で用意したEventTriggerに対応するメソッドを登録します。

LeftButtonの場合(※画像ではScript名が異なります)
スクリーンショット 2018-04-04 11.23.32.png

4.ScrollbarをScrollViewCtr.csの「Scrollbar」にアタッチします。
スクリーンショット 2018-04-04 16.13.53.png

5.Gameをプレイして動作するか確認してみてください。

コードサンプル

ScrollViewCtr.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class ScrollViewCtr : MonoBehaviour
{
    //for ScrollButton
    public Scrollbar _Scrollbar;

    //Coroutineを中断するために変数として宣言しておく
    Coroutine _Coroutine;

    //スクロールスピード
    [SerializeField]float ScrollSpeed = 0.2f;

    //LeftButtonに登録
    public void ScrollLeft ()
    {
        if (_Coroutine != null) {
            StopCoroutine (_Coroutine);
        }
        _Coroutine = StartCoroutine (TimeForScrollLeft ());
    }

    //LeftestButtonに登録
    public void ScrollLeftest ()
    {
        if (_Coroutine != null) {
            StopCoroutine (_Coroutine);
        }
        _Coroutine = StartCoroutine (TimeForScrollLeft (300f));
    }

    //左スクロールコルーチン
    IEnumerator TimeForScrollLeft (float SpeedRate = 1f)
    {
        while (_Scrollbar.value > 0) {
            _Scrollbar.value -= Time.deltaTime * ScrollSpeed * SpeedRate;
            yield return null;
        }
    }

    //Rightボタンに登録
    public void ScrollRight ()
    {
        if (_Coroutine != null) {
            StopCoroutine (_Coroutine);
        }
        _Coroutine = StartCoroutine (TimeForScrollRight ());
    }

    //RightestButtonに登録
    public void ScrollRightest ()
    {
        if (_Coroutine != null) {
            StopCoroutine (_Coroutine);
        }
        _Coroutine = StartCoroutine (TimeForScrollRight (300f));
    }

    //右スクロールコルーチン
    IEnumerator TimeForScrollRight (float SpeedRate = 1f)
    {
        while (_Scrollbar.value < 1) {
            _Scrollbar.value += Time.deltaTime * ScrollSpeed * SpeedRate;
            yield return null;
        }
    }

    //EventTriggerのPointerUpイベントに登録する処理
    public void StopScroll ()
    {
        if (_Coroutine != null) {
            StopCoroutine (_Coroutine);
        }
    }
}

簡単な解説

メソッドをEventTriggerのPointDownに登録すると、RaycastTargetを押した際にメソッドが実行されます。今回登録したメソッドは、ScrollViewのScrollbar.valueを変化させるものです。

LeftButtonを例に取ります。
ScrollLeftest ()では、既に動いているコルーチンを停止して、その後TimeForScrollLeft()コルーチンを開始してます。

この時_Coroutine = StartCoroutine (TimeForScrollLeft ());としているのは、後でStopCoroutine (_Coroutine);で停止させるためです。

次にTimeForScrollLeft (float SpeedRate = 1f)を見ます。

while (true) {
            //何かの処理
            yield return null;
        }

コルーチン中でこう書くと、while文の条件を満たすまで時間経過ごとに処理を行うことができます。今回はScrollbar.valueの値をdeltaTimeに応じて変えてScrollbarを移動させてます。

ScrollLeftest ()ではScrollbar.valueの変化速度を300倍にして、一瞬で移動したように見えるようにしてます。単純に_Scrollbar.value = 1f;としても良いと思います。

最後にStopScroll ()をEventTrigger PointerUpに登録することで、RaycastTargetを押すのをやめた時にコルーチンを停止してスクロールをやめるようにしています。PointerDownに登録するメソッドでも最初にコルーチンを停止するようにしてますが、これは同時にボタンを押した時に後から押した方のメソッドを実行させるためです。

以上になります。

参考になった場合はいいねをお願いします〜