UnityのScrollRectのスクロール位置を調整

2015-05-02

UnityのuGUIでスクロールビューを作る - テラシュールブログ を参考にしてスクロールビューを作ったが、その時に初期の表示位置を設定したかったのでやり方を調べた。

縦スクロールの場合、ScrollRectverticalNormalizedPositionでスクロール位置を読み書きできる。で指定の要素を中心に表示したいかというのを与えられるようにしたい。

あとは算数の問題で、ScrollRectContentの高さと要素数から計算できる。Contentに追加しているスクリプトに以下の様なメソッドを追加してやる:

// ScrollController.cs
public void SetCenterItem(int index) {
RectTransform scrollViewTfm = transform.parent as RectTransform;
float height = scrollViewTfm.sizeDelta.y;
float contentHeight = (transform as RectTransform).sizeDelta.y;
if (contentHeight <= height) // コンテンツよりスクロールエリアのほうが広いので、スクロールしなくてもすべて表示されている
return;

int n = transform.childCount;
float y = (index + 0.5f) / n; // 要素の中心座標
float scrollY = y - 0.5f * height / contentHeight;
float ny = scrollY / (1 - height / contentHeight); // ScrollRect用に正規化した座標

ScrollRect scrollRect = scrollViewTfm.GetComponent<ScrollRect>();
scrollRect.verticalNormalizedPosition = Mathf.Clamp(1 - ny, 0, 1); // Y軸は下から上なので反転してやる
}

あとスクリプトからノードを生成した場合、ContentRectTransformの高さ(sizeDelta.y)がすぐには反映されないようなので、ちょっと待ってから(ContentSizeFilterUpdateが呼び出された後に?)上記のメソッドを呼び出す必要がある。

【Unity】StartCoroutineでラムダ式を使用できるようにするラッパークラス - コガネブログを使って、

ScrollController scroll = content.GetComponent<ScrollController>();
CoroutineCommon.CallWaitForOneFrame(() => {
scroll.SetCenterItem(index);
});