Unity Scroll 通用性

本篇主要介绍制作以一个scroll  主要支持无限循环,和简单易用。

1:创建UGUI对象 Scroll View

2:给Scroll View添加 EasyScrollMove组建

3:设置属性:IsVertical 代表是否竖方向滑动  Row 代表每行或者每列多少个 

4:再Content下面创建一个 Item对象 作为需要使用的子物体。并且赋值给EasyScrollMove的Prefab属性

5:初始化使用InitScrollview方法

组建代码如下:

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class EasyScrollMove : MonoBehaviour
{
    private ScrollRect scrollRect;
    private RectTransform gridRect;
    public Action UpDateElement;
    public RectOffset padding;
    public Vector2 spacing;
    public int Row = 1;
    public bool IsVertical = true;
    public GameObject prefab;

    private int itemCount = 10;
    [HideInInspector]
    public List prefabsList = new List();
    private int instantiatCount;
    float itemHeight;
    float itemWidth;
    int upIndex = 0;
    int botomIndex = 0;
    int oldMoveIndex = 0;
    float postionY = 0;
    float scrollRectHeight;
    float scrollRectWidth;

    private float totalLength;

    // Use this for initialization
    void Start()
    {

    }
    ///


    /// 初始化函数
    ///

    /// 更新item需要回调的函数,参数为索引和对象
    /// item的总数量
    public void InitScrollview(Action UpDateElement, int maxCount)
    {

        this.scrollRect = gameObject.GetComponent();
        if (scrollRect.content != null)
            gridRect = scrollRect.content.GetComponent();
        else
            gridRect = gameObject.transform.GetChild(0).GetChild(0).GetComponent();
        this.UpDateElement = UpDateElement;
        this.itemCount = maxCount;
        scrollRectHeight = scrollRect.GetComponent().sizeDelta.y;
        scrollRectWidth = scrollRect.GetComponent().sizeDelta.x;
        scrollRect.onValueChanged = new ScrollRect.ScrollRectEvent();
        scrollRect.onValueChanged.AddListener(OnScrollValueChanged);
        if (prefab == null)
            prefab = gameObject.transform.GetChild(0).GetChild(0).GetChild(0).gameObject;
        prefab.gameObject.SetActive(false);

        itemHeight = prefab.GetComponent().sizeDelta.y + spacing.y;
        itemWidth = prefab.GetComponent().sizeDelta.x + spacing.x;

        if (IsVertical)
        {
            instantiatCount = (Mathf.CeilToInt(scrollRect.GetComponent().sizeDelta.y / itemHeight) + 1) * Row;
        }
        else
        {
            instantiatCount = (Mathf.CeilToInt(scrollRect.GetComponent().sizeDelta.x / itemWidth) + 1) * Row;
        }


        if (instantiatCount > maxCount)
            instantiatCount = maxCount;
        if (IsVertical)
        {
            float basLength = gridRect.sizeDelta.y;
            totalLength = (maxCount / Row + (maxCount % Row == 0 ? 0 : 1)) * itemHeight;
            gridRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, totalLength);
            totalLength = gridRect.sizeDelta.y - basLength;
        }
        else
        {
            float basLength = gridRect.sizeDelta.x;
            totalLength = (maxCount / Row + (maxCount % Row == 0 ? 0 : 1)) * itemWidth;
            gridRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, totalLength);
            totalLength = gridRect.sizeDelta.x - basLength;
        }
        Debug.Log("totalLength:" + totalLength);


        for (int i = 0; i < instantiatCount; i++)
        {
            GameObject gob = (Instantiate(prefab, gridRect.transform) as GameObject);
            gob.gameObject.SetActive(true);

            prefabsList.Add(gob);
            if (UpDateElement != null)
            {
                UpDateElement(i, gob);
            }
            if (IsVertical)
            {
                gob.GetComponent().anchoredPosition = new Vector2(i % Row * itemWidth, -(i / Row) * itemHeight);
            }
            else
            {
                gob.GetComponent().anchoredPosition = new Vector2(i / Row * itemWidth, -(i % Row) * itemHeight);
            }


        }
        botomIndex = (instantiatCount) - 1;
        if (IsVertical)
        {
            postionY = gridRect.anchoredPosition.y;
            if (postionY < itemHeight*0.5f)
                postionY = itemHeight * 0.5f;
            else if(postionY> totalLength - itemHeight * 0.5f)
            {
                postionY = totalLength - itemHeight * 0.5f;
            }
            oldMoveIndex = Mathf.FloorToInt(Mathf.Abs(postionY / itemHeight / Row));
        }
        else
        {
            postionY = gridRect.anchoredPosition.x;
            if(postionY> -itemHeight * 0.5f)
            {
                postionY = -itemHeight * 0.5f;
            }else if(postionY < -1 * totalLength+ itemHeight * 0.5f)
            {
                postionY = -1 * totalLength+ itemHeight * 0.5f;
            }
            oldMoveIndex = Mathf.FloorToInt(Mathf.Abs(postionY / itemWidth / Row));
        }

        if (oldMoveIndex < 0)
            oldMoveIndex = 0;
        else if(oldMoveIndex>= this.itemCount)
        {
            oldMoveIndex = this.itemCount - 1;
        }
    }

    void OnScrollValueChanged(Vector2 vec)
    {
        float curPosY = 0;
        int curMoveIndex = 0;
        int offsetCount = 0;
        if (IsVertical)
        {
            curPosY = gridRect.anchoredPosition.y;
            if (curPosY <= itemHeight * 0.5f)
                curPosY = itemHeight * 0.5f;
            if(curPosY >= totalLength- itemHeight * 0.5f)
            {
                curPosY = totalLength- itemHeight * 0.5f;
            }
            /*
            if (curPosY <= 0 || curPosY >= totalLength)
            {
                return;
            }
            */
            curMoveIndex = Mathf.FloorToInt(Mathf.Abs(curPosY / itemHeight / Row));
            offsetCount = Mathf.Abs(curMoveIndex - oldMoveIndex);
        }
        else
        {
            curPosY = gridRect.anchoredPosition.x;
            if(curPosY >= -itemHeight * 0.5f)
            {
                curPosY = -itemHeight * 0.5f;
            }
            if(curPosY <= -1 * totalLength + itemHeight * 0.5f)
            {
                curPosY = -1 * totalLength + itemHeight * 0.5f;
            }
            /*
            if (curPosY >= 0 || curPosY <= -1 * totalLength)
            {
                return;
            }
            */
            curMoveIndex = Mathf.FloorToInt(Mathf.Abs(curPosY / itemWidth / Row));
            offsetCount = Mathf.Abs(curMoveIndex - oldMoveIndex);
        }

        float itemLong = itemHeight;
        float scrollRectLong = scrollRectHeight;
        if (!IsVertical)
        {
            itemLong = itemWidth;
            scrollRectLong = scrollRectWidth;
        }

        for (int i = 0; i < offsetCount; i++)
        {

            if (IsVertical)
            {
                if (curPosY > postionY)
                {
                    if (upIndex < itemCount - Row && botomIndex < itemCount - Row)
                    {
                        upIndex += Row;
                        botomIndex += Row;
                        updateListviewPos(true);
                    }

                }
                else if (curPosY < postionY)
                {
                    if (upIndex > 0 && botomIndex > 0)
                    {
                        upIndex -= Row;
                        botomIndex -= Row;
                        updateListviewPos(false);
                    }

                }
            }
            else
            {
                if (curPosY > postionY)
                {

                    if (upIndex > 0 && botomIndex > 0)
                    {
                        upIndex -= Row;
                        botomIndex -= Row;
                        updateListviewPos(false);
                    }

                }
                else if (curPosY < postionY)
                {

                    if (upIndex < itemCount - Row && botomIndex < itemCount - Row)
                    {
                        upIndex += Row;
                        botomIndex += Row;
                        updateListviewPos(true);
                    }
                }
            }

        }
        oldMoveIndex = curMoveIndex;
        postionY = curPosY;

        if (oldMoveIndex < 0)
            oldMoveIndex = 0;
        else if (oldMoveIndex >= this.itemCount)
        {
            oldMoveIndex = this.itemCount - 1;
        }
    }

    void updateListviewPos(bool isMoveUp)
    {
        int tempIndex = 0;
        if (IsVertical)
        {
            if (isMoveUp)
            {
                GameObject gob = prefabsList[tempIndex];
                prefabsList.RemoveAt(tempIndex);
                prefabsList.Add(gob);
                if (gob)
                {
                    gob.GetComponent().anchoredPosition = new Vector2(botomIndex % Row * itemWidth, -botomIndex / Row * itemHeight);
                }
                if (UpDateElement != null)
                {
                    UpDateElement(botomIndex, gob);
                }
            }
            else
            {
                tempIndex = prefabsList.Count - 1;
                GameObject gob = prefabsList[tempIndex];
                prefabsList.RemoveAt(tempIndex);
                prefabsList.Insert(0, gob);
                if (gob)
                {
                    gob.GetComponent().anchoredPosition = new Vector2(upIndex % Row * itemWidth, -upIndex / Row * itemHeight);
                }
                if (UpDateElement != null)
                {
                    UpDateElement(upIndex, gob);
                }
            }
        }
        else
        {
            if (isMoveUp)
            {
                GameObject gob = prefabsList[tempIndex];
                prefabsList.RemoveAt(tempIndex);
                prefabsList.Add(gob);
                if (gob)
                {
                    gob.GetComponent().anchoredPosition = new Vector2(botomIndex / Row * itemWidth, -botomIndex % Row * itemHeight);
                }

                if (UpDateElement != null)
                {
                    UpDateElement(botomIndex, gob);
                }
            }
            else
            {
                tempIndex = prefabsList.Count - 1;
                GameObject gob = prefabsList[tempIndex];
                prefabsList.RemoveAt(tempIndex);
                prefabsList.Insert(0, gob);

                if (gob)
                {
                    gob.GetComponent().anchoredPosition = new Vector2(upIndex / Row * itemWidth, -upIndex % Row * itemHeight);
                }

                if (UpDateElement != null)
                {
                    UpDateElement(upIndex, gob);
                }
            }
        }

    }
}

你可能感兴趣的:(unity)