概述
本篇主要介绍制作以一个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<int, GameObject> 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<GameObject> prefabsList = new List<GameObject>();
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()
{
}
/// <summary>
/// 初始化函数
/// </summary>
/// <param name="UpDateElement">更新item需要回调的函数,参数为索引和对象</param>
/// <param name="maxCount">item的总数量</param>
public void InitScrollview(Action<int, GameObject> UpDateElement, int maxCount)
{
this.scrollRect = gameObject.GetComponent<ScrollRect>();
if (scrollRect.content != null)
gridRect = scrollRect.content.GetComponent<RectTransform>();
else
gridRect = gameObject.transform.GetChild(0).GetChild(0).GetComponent<RectTransform>();
this.UpDateElement = UpDateElement;
this.itemCount = maxCount;
scrollRectHeight = scrollRect.GetComponent<RectTransform>().sizeDelta.y;
scrollRectWidth = scrollRect.GetComponent<RectTransform>().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<RectTransform>().sizeDelta.y + spacing.y;
itemWidth = prefab.GetComponent<RectTransform>().sizeDelta.x + spacing.x;
if (IsVertical)
{
instantiatCount = (Mathf.CeilToInt(scrollRect.GetComponent<RectTransform>().sizeDelta.y / itemHeight) + 1) * Row;
}
else
{
instantiatCount = (Mathf.CeilToInt(scrollRect.GetComponent<RectTransform>().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<RectTransform>().anchoredPosition = new Vector2(i % Row * itemWidth, -(i / Row) * itemHeight);
}
else
{
gob.GetComponent<RectTransform>().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<RectTransform>().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<RectTransform>().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<RectTransform>().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<RectTransform>().anchoredPosition = new Vector2(upIndex / Row * itemWidth, -upIndex % Row * itemHeight);
}
if (UpDateElement != null)
{
UpDateElement(upIndex, gob);
}
}
}
}
}
最后
以上就是忧心金毛为你收集整理的Unity Scroll 通用性的全部内容,希望文章能够帮你解决Unity Scroll 通用性所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复