Edited at

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

More than 3 years have passed since last update.

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);
}
}