纳金网
标题:
NGUI无限滑动(转载)
[打印本页]
作者:
烟雨
时间:
2014-9-11 01:34
标题:
NGUI无限滑动(转载)
最近由于工作需要,就开始研究NGUI滑动。刚开始参考NGUI自带的循环滑动,利用隐藏和显示,提高GPU的渲染,但是效果依旧不是很理想。在同事提醒下,添加缓存列表,不断刷新当前裁剪区域里的数据,最总完成了需求。在网上也参考了很多资料,今天恰好闲下来,就拿出来大家分享下,哈哈。代码附上:
主要分为三部分:
1.重写UIScrollView和UICustomDragScrollView两个脚本
2.核心脚本NGUIDynamicScrollBase ,计算滑动和播放位移动画
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 扩展NGUIScroll滑动类,需要继承该类进行开发
/// </summary>
public abstract class NGUIDynamicScrollBase : MonoBehaviour
{
//每个列表项数据初始化
abstract protected void ResetItemData(GameObject go, int index);
public UIPanel panel;
public UIGrid grid;
//目标prefab
public GameObject prefab;
//宽度
public int cellHeight = 60;
//高度
public int cellWidth = 700;
//裁剪区的高度
private float m_height;
//裁剪区的宽度
private int m_maxLine;
//当前滑动的列表
protected GameObject[] m_cellList;
//当前需要滑动的列表总数
private int m_dataListCount;
//自定义滑动
private UICustomScrollView mDrag;
//最后一次的滑动位置
private float lastY = -1;
private Vector3 defaultVec;
// Use this for initialization
protected void BaseOnEnable()
{
GetConfiguration();
}
// Update is called once per frame
protected void BaseUpdate()
{
if (panel.transform.localPosition.y != lastY)
{
Validate();
lastY = panel.transform.localPosition.y;
}
}
//设置当前列表中的
protected int DataListCount
{
get { return m_dataListCount; }
set{
m_dataListCount = value;
AddItem(m_dataListCount);
PlayMoveAnimation(m_cellList);
}
}
#region private Functions
//初始化配置数据
private void GetConfiguration()
{
//物体默认位置
defaultVec = new Vector3(0, cellHeight, 0);
//裁剪区域的高度
m_height = panel.height;
//裁剪区域中最多显示的cellItem数量
m_maxLine = Mathf.CeilToInt(m_height / cellHeight) + 1;
//初始化CellList
m_cellList = new GameObject[m_maxLine];
//创建Item,默认为不可显示状态
CreateItem();
}
//创建Item
private void CreateItem()
{
for (int i = 0; i < m_maxLine; i++)
{
GameObject go = null;
go = (GameObject)Instantiate(prefab);
go.gameObject.SetActive(false);
go.GetComponent<UICustomDragScrollView>().scrollView = panel.GetComponent<UICustomScrollView>();
AddChild(grid.gameObject, go);
go.transform.localScale = Vector3.one;
go.transform.localPosition = new Vector3(cellWidth * AllScale.ResolutionScale, -i * cellHeight, 0);
m_cellList[i] = go;
go.gameObject.SetActive(false);
}
}
//验证当前区域中的需要显示的CellItem
private void Validate()
{
Vector3 position = panel.transform.localPosition;
float _ver = Mathf.Max(position.y, 0);
int startIndex = Mathf.FloorToInt(_ver / cellHeight);
int endIndex = Mathf.Min(DataListCount, startIndex + m_maxLine);
GameObject cell;
int index = 0;
for (int i = startIndex; i < startIndex + m_maxLine; i++)
{
cell = m_cellList[index];
if (i < endIndex)
{
//开始渲染
cell.gameObject.SetActive(true);
//重新填充数据
ResetItemData(cell, i);
//改变位置
cell.transform.localPosition = new Vector3(cell.transform.localPosition.x, i * -cellHeight, 0);
cell.name = "Item_" + index;
}
else
{
cell.transform.localPosition = defaultVec;
// cell.gameObject.SetActive(false);
}
index++;
}
}
//重新计算包围合的大小
private void UpdateBounds(int count)
{
Vector3 vMin = new Vector3();
vMin.x = -grid.transform.localPosition.x;
vMin.y = grid.transform.localPosition.y - count * cellHeight;
vMin.z = grid.transform.localPosition.z;
Bounds b = new Bounds(vMin, Vector3.one);
b.Encapsulate(grid.transform.localPosition);
if (mDrag == null) mDrag = panel.GetComponent<UICustomScrollView>();
mDrag.bounds = b;
mDrag.UpdateScrollbars(true);
mDrag.RestrictWithinBounds(true);
}
//根据新的数量来重新绘制
private void AddItem(int count)
{
Validate();
UpdateBounds(count);
}
//增加孩子节点
void AddChild(GameObject parent, GameObject go)
{
Transform t = go.transform;
t.parent = parent.transform;
t.localPosition = Vector3.zero;
t.localRotation = Quaternion.identity;
t.localScale = Vector3.one;
go.layer = parent.layer;
}
//播放开始加载的位移动画
void PlayMoveAnimation(GameObject[] list)
{
Vector3 to;
Vector3 from;
for (int i = 0; i < list.Length; i++)
{
from = list[i].transform.localPosition;
from = new Vector3(cellWidth*AllScale.ResolutionScale, from.y, 0);
to = new Vector3(0, from.y, 0);
list[i].transform.localPosition = from;
TweenPosition tp = TweenPosition.Begin(list[i], 0.8f, to);
tp.delay = 0.1f;
tp.from = from;
tp.to = to;
tp.duration = (i + 2) * 0.1f;
tp.method = UITweener.Method.EaseIn;
}
}
#endregion
}
复制代码
3.将列表中的Prefab设置为向上对齐
作者:
hyui
时间:
2014-9-11 02:13
Thanks for this script !
作者:
Kadina
时间:
2014-9-11 07:07
感谢分享!
作者:
cgjch8
时间:
2014-9-11 08:47
感谢分享
作者:
HIDEOKOJIMA
时间:
2014-9-11 09:45
感谢分享!
作者:
tophkiss
时间:
2014-9-11 10:20
感谢分享
作者:
今夕何夕
时间:
2014-9-11 15:34
Thanks for sharing !
作者:
今夕何夕
时间:
2014-9-11 15:42
Thanks for sharing !
作者:
yaoweihuli
时间:
2014-9-12 10:41
感谢分享,非常不错!!!!
作者:
CosmosFlow
时间:
2014-9-12 18:41
代码不全。。转自哪里?
作者:
Kadina
时间:
2014-9-13 07:40
Thanks for sharing !
欢迎光临 纳金网 (http://old.narkii.com/club/)
Powered by Discuz! X2.5