LoginSignup
32
24

More than 5 years have passed since last update.

Unity uGUI スクロールビューをスナップさせる

Last updated at Posted at 2015-05-25

Unity - uGUI スクロールビューを分割毎にスナップする - Qiita - http://qiita.com/imatomi/items/61db31536a9f08a67440

の改良版。

元ページにあるコードの位置取得のための計算式の意味はパッと見よくわからないし、forループを使っているのも意図がわからないし、最終的に必要であろうデータのインデックスも取れないので改良した。

外側からインデックスを変更してforcePositionUpdateフラグを用いればこのコードの外側から位置を変更可能である。

また、元ページにあるように、Editorスクリプトを追加する必要がある。それに関しては元ページを参照して各自実装してほしい。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class ScrollSnapSelector : ScrollRect
{
    public int hIndex;
    public int vIndex;

    public int horizontalPages = 3;
    public int verticalPages = 3;
    public float smooth = 10f;

    Vector2 targetPosition;
    float hPerPage;
    float vPerPage;
    bool dragging;

    public bool forcePositionUpdate = false;

    void Awake()
    {
        hPerPage = 1.0f / (float)(horizontalPages - 1);
        vPerPage = 1.0f / (float)(verticalPages - 1);
    }

    void Start()
    {
        targetPosition = GetSnapPosition();
    }

    void Update()
    {
        if (!dragging && normalizedPosition != targetPosition)
        {
            normalizedPosition = Vector2.Lerp(normalizedPosition, targetPosition, smooth * Time.deltaTime);
            if (Vector2.Distance(normalizedPosition, targetPosition) < 0.009f)
            {
                normalizedPosition = targetPosition;
            }
        }
        if (forcePositionUpdate)
        {
            forcePositionUpdate = false;
            targetPosition = GetSnapPosition();
        }
    }

    public override void OnBeginDrag(PointerEventData eventData)
    {
        base.OnBeginDrag(eventData);
        dragging = true;
    }

    public override void OnEndDrag(PointerEventData eventData)
    {
        base.OnEndDrag(eventData);
        UpdateIndex();
        targetPosition = GetSnapPosition();
        dragging = false;
    }

    void UpdateIndex()
    {
        int xPage = -1;
        int yPage = -1;
        if (horizontal && horizontalPages > 0)
        {
            xPage = Mathf.RoundToInt(normalizedPosition.x / hPerPage);
            xPage = Mathf.Clamp(xPage, 0, horizontalPages - 1);
            hIndex = xPage;
        }

        if (vertical && verticalPages > 0)
        {
            yPage = Mathf.RoundToInt(normalizedPosition.y / vPerPage);
            yPage = Mathf.Clamp(yPage, 0, verticalPages - 1);
            vIndex = yPage;
        }
    }

    Vector2 GetSnapPosition()
    {
        return new Vector2(horizontal && horizontalPages > 0 ? hIndex * hPerPage : normalizedPosition.x, vertical && verticalPages > 0 ? vIndex * vPerPage : normalizedPosition.y);
    }
}
32
24
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
24