NGUIでUIGridの中央にあるオブジェクトを取得


前回の記事ではスクロールビュー以下のGridに含まれる要素を取得しました。
NGUIでUIGrid直下のUIWidgetオブジェクトを取得

スクロールの最中にGridの中央にあるオブジェクトを調べたいことってありますよね?俺はありました。
いわゆるカルーセルみたいな機能を実現するために必要になったので、スクロールの中央を調べる方法を紹介します。


using UnityEngine;
using System.Collections;
using System.Linq;

public class CenteringGrid : MonoBehaviour {
    public UIScrollView scrollView;

    private UICenterOnChild mCenter;
    private string mCurrentItemName;
    private int mCuurentItemIdx;
    private UIWidget[] mScrollObjs;

    public void Start() {
    // UIScrollViewの子であるUIGridを取得
        UIGrid grid = scrollView.GetComponentInChildren<UIGrid>();

        // UIGridにUICenterOnChildコンポーネントが設定されている前提
        mCenter = grid.GetComponent<UICenterOnChild>();
        mCenter.onFinished = OnGridMoveFinished;
        mCenter.onCenter = OnGridCenter;

        // Grid直下のWidgetのみを取得
        mScrollObjs = grid.GetComponentsInChildren<UIWidget> ().Where(obj => obj.transform.parent == grid.transform).ToArray();
    }

    public void OnGridCenter(GameObject obj){
        updatePageNavi (obj.name);
    }

    public void OnGridMoveFinished(){
        updatePageNavi (mCenter.centeredObject.name);
    }

    private void updatePageNavi(string name){
        // 中央にいるオブジェクトの名称と比較、変化していれば処理
        if (name != mCurrentItemName) {
            mCurrentItemName = name;

            // Gridに設定されたオブジェクトから中心オブジェクトと一致するものを探してインデックスを取得
            foreach (var item in mScrollObjs.Select((val,idx)=> new {val,idx})) {
                if(item.val.name.Equals(name) ) {
                    mCuurentItemIdx = item.idx;
                    break;
                }
            }
            Debug.Log("Current idx="+mCuurentItemIdx);
        }
    }
}

※ちなみに以下の部分は、LINQのSelectを使うことでforeachで回しながら値とインデックスを同時に取得しています。

foreach (var item in mScrollObjs.Select((val,idx)=> new {val,idx}))

インデックスのカウント用に変数を用意しなくていいので便利ですよね。LINQ楽しいです!

以上です