使用NGUI 3.5.5创建高效的超大Scroll View
2014-11-26 17:02
155 查看
在使用NGUI的Scroll View的时候,碰到Scroll Item太多的话(超过100个),在滑动的过程中就会明显掉帧。究其原因就是NGUI每帧会对所有的Scroll Item进行更新,无论它是否显示。
NGUI 3.5.5加入了UIWrapContent,它会将不显示的Scroll Item设为disabled,这样就使得每帧更新的Scroll Item减少到当前显示的那几个,就再也不会出现掉帧的情况了。
不过UIWrapContent只能创建循环的Scroll View,不过只需要简单的几处修改,就能实现在普通的Scroll View上。
复制一份
修改后的代码如下:
修改初始化代码
修改后的代码如下:
注释创建首尾循环的代码
修改
修改后的代码如下:
最后,使用NGUI自带的例子
最后完整的代码如下,UIScrollView的代码别忘了
文章转载自使用NGUI
3.5.5创建高效的超大Scroll View,感谢JJCat提供好文章
NGUI 3.5.5加入了UIWrapContent,它会将不显示的Scroll Item设为disabled,这样就使得每帧更新的Scroll Item减少到当前显示的那几个,就再也不会出现掉帧的情况了。
不过UIWrapContent只能创建循环的Scroll View,不过只需要简单的几处修改,就能实现在普通的Scroll View上。
复制一份
UIWrapContent.cs,重命名为
UIBetterGrid.cs,修改类名
// line: 19 - 20, file: UIWrapContent.cs [AddComponentMenu("NGUI/Interaction/Wrap Content")] public class UIWrapContent : MonoBehaviour
修改后的代码如下:
// line: 19 - 20, file: UIBetterGrid.cs [AddComponentMenu("NGUI/Interaction/Better Grid")] public class UIBetterGrid : MonoBehaviour
修改初始化代码
// line: 52 - 54, file: UIWrapContent.cs mScroll.restrictWithinPanel = false; if (mScroll.dragEffect == UIScrollView.DragEffect.MomentumAndSpring) mScroll.dragEffect = UIScrollView.DragEffect.Momentum;
修改后的代码如下:
// line: 52 - 54, file: UIBetterGrid.cs mScroll.restrictWithinPanel = true; //if (mScroll.dragEffect == UIScrollView.DragEffect.MomentumAndSpring) //mScroll.dragEffect = UIScrollView.DragEffect.Momentum;
注释创建首尾循环的代码
// line 159 - 170, file: UIBetterGrid.cs //if (distance < -extents) //{ // t.localPosition += new Vector3(extents * 2f, 0f, 0f); // distance = t.localPosition.x - center.x; // UpdateItem(t, i); //} //else if (distance > extents) //{ // t.localPosition -= new Vector3(extents * 2f, 0f, 0f); // distance = t.localPosition.x - center.x; // UpdateItem(t, i); //} // line 190 - 201, file: UIBetterGrid.cs //if (distance < -extents) //{ // t.localPosition += new Vector3(0f, extents * 2f, 0f); // distance = t.localPosition.y - center.y; // UpdateItem(t, i); //} //else if (distance > extents) //{ // t.localPosition -= new Vector3(0f, extents * 2f, 0f); // distance = t.localPosition.y - center.y; // UpdateItem(t, i); //}
修改
UIScrollView.cs
// line 173, file: UIWrapContent.cs mBounds = NGUIMath.CalculateRelativeWidgetBounds(mTrans, mTrans);
修改后的代码如下:
// line 173, file: UIBetterGrid.cs mBounds = NGUIMath.CalculateRelativeWidgetBounds(mTrans, mTrans,true);
最后,使用NGUI自带的例子
Example 7 - Scroll View (Panel).unity测试下性能吧。把例子中的UIGrid替换为UIBetterGrid,试试复制成百上千个scroll item,跑起来一点也不会卡。
最后完整的代码如下,UIScrollView的代码别忘了
//---------------------------------------------- // NGUI: Next-Gen UI kit // Copyright © 2011-2014 Tasharen Entertainment //---------------------------------------------- using UnityEngine; /// <summary> /// This script makes it possible for a scroll view to wrap its content, creating endless scroll views. /// Usage: simply attach this script underneath your scroll view where you would normally place a UIGrid: /// /// + Scroll View /// |- UIWrappedContent /// |-- Item 1 /// |-- Item 2 /// |-- Item 3 /// </summary> [AddComponentMenu("NGUI/Interaction/Wrap Content")] public class UIBetterGrid : MonoBehaviour { /// <summary> /// Width or height of the child items for positioning purposes. /// </summary> public int itemSize = 100; /// <summary> /// Whether the content will be automatically culled. Enabling this will improve performance in scroll views that contain a lot of items. /// </summary> public bool cullContent = true; Transform mTrans; UIPanel mPanel; UIScrollView mScroll; bool mHorizontal = false; BetterList<Transform> mChildren = new BetterList<Transform>(); /// <summary> /// Initialize everything and register a callback with the UIPanel to be notified when the clipping region moves. /// </summary> protected virtual void Start () { SortBasedOnScrollMovement(); WrapContent(); if (mScroll != null) { mScroll.GetComponent<UIPanel>().onClipMove = OnMove; mScroll.restrictWithinPanel = true; //if (mScroll.dragEffect == UIScrollView.DragEffect.MomentumAndSpring) // mScroll.dragEffect = UIScrollView.DragEffect.Momentum; } } /// <summary> /// Callback triggered by the UIPanel when its clipping region moves (for example when it's being scrolled). /// </summary> protected virtual void OnMove (UIPanel panel) { WrapContent(); } /// <summary> /// Immediately reposition all children. /// </summary> [ContextMenu("Sort Based on Scroll Movement")] public void SortBasedOnScrollMovement () { if (!CacheScrollView()) return; // Cache all children and place them in order mChildren.Clear(); for (int i = 0; i < mTrans.childCount; ++i) mChildren.Add(mTrans.GetChild(i)); // Sort the list of children so that they are in order if (mHorizontal) mChildren.Sort(UIGrid.SortHorizontal); else mChildren.Sort(UIGrid.SortVertical); ResetChildPositions(); } /// <summary> /// Immediately reposition all children, sorting them alphabetically. /// </summary> [ContextMenu("Sort Alphabetically")] public void SortAlphabetically () { if (!CacheScrollView()) return; // Cache all children and place them in order mChildren.Clear(); for (int i = 0; i < mTrans.childCount; ++i) mChildren.Add(mTrans.GetChild(i)); // Sort the list of children so that they are in order mChildren.Sort(UIGrid.SortByName); ResetChildPositions(); } /// <summary> /// Cache the scroll view and return 'false' if the scroll view is not found. /// </summary> protected bool CacheScrollView () { mTrans = transform; mPanel = NGUITools.FindInParents<UIPanel>(gameObject); mScroll = mPanel.GetComponent<UIScrollView>(); if (mScroll == null) return false; if (mScroll.movement == UIScrollView.Movement.Horizontal) mHorizontal = true; else if (mScroll.movement == UIScrollView.Movement.Vertical) mHorizontal = false; else return false; return true; } /// <summary> /// Helper function that resets the position of all the children. /// </summary> void ResetChildPositions () { for (int i = 0; i < mChildren.size; ++i) { Transform t = mChildren[i]; t.localPosition = mHorizontal ? new Vector3(i * itemSize, 0f, 0f) : new Vector3(0f, -i * itemSize, 0f); } } /// <summary> /// Wrap all content, repositioning all children as needed. /// </summary> public void WrapContent () { float extents = itemSize * mChildren.size * 0.5f; Vector3[] corners = mPanel.worldCorners; for (int i = 0; i < 4; ++i) { Vector3 v = corners[i]; v = mTrans.InverseTransformPoint(v); corners[i] = v; } Vector3 center = Vector3.Lerp(corners[0], corners[2], 0.5f); if (mHorizontal) { float min = corners[0].x - itemSize; float max = corners[2].x + itemSize; for (int i = 0; i < mChildren.size; ++i) { Transform t = mChildren[i]; float distance = t.localPosition.x - center.x; //if (distance < -extents) //{ // t.localPosition += new Vector3(extents * 2f, 0f, 0f); // distance = t.localPosition.x - center.x; // UpdateItem(t, i); //} //else if (distance > extents) //{ // t.localPosition -= new Vector3(extents * 2f, 0f, 0f); // distance = t.localPosition.x - center.x; // UpdateItem(t, i); //} if (cullContent) { distance += mPanel.clipOffset.x - mTrans.localPosition.x; if (!UICamera.IsPressed(t.gameObject)) NGUITools.SetActive(t.gameObject, (distance > min && distance < max), false); } } } else { float min = corners[0].y - itemSize; float max = corners[2].y + itemSize; for (int i = 0; i < mChildren.size; ++i) { Transform t = mChildren[i]; float distance = t.localPosition.y - center.y; //if (distance < -extents) //{ // t.localPosition += new Vector3(0f, extents * 2f, 0f); // distance = t.localPosition.y - center.y; // UpdateItem(t, i); //} //else if (distance > extents) //{ // t.localPosition -= new Vector3(0f, extents * 2f, 0f); // distance = t.localPosition.y - center.y; // UpdateItem(t, i); //} if (cullContent) { distance += mPanel.clipOffset.y - mTrans.localPosition.y; if (!UICamera.IsPressed(t.gameObject)) NGUITools.SetActive(t.gameObject, (distance > min && distance < max), false); } } } } /// <summary> /// Want to update the content of items as they are scrolled? Override this function. /// </summary> protected virtual void UpdateItem (Transform item, int index) {} }
文章转载自使用NGUI
3.5.5创建高效的超大Scroll View,感谢JJCat提供好文章
相关文章推荐
- 使用NGUI 3.5.5创建高效的超大Scroll View
- 在ASP.Net4.0中使用QueryExtender控件创建高效的搜索页面
- 使用rails高效开发之快速创建控制器 视图 模型和数据库文件
- unity3D使用NGUI创建gameobject时game窗口不显示问题
- unityTaidou(一)NGUI之列表的创建与使用
- NGUI使用心得之使用TexturePacker创建图集
- 构建高性能java程序-使用mapped file创建超大的矩阵
- 使用JS创建table的高效方法
- Uber如何使用go语言创建高效的查询服务
- NGUI使用4——创建动态字体
- 使用Java继承与泛型特性创建高效与安全的DAO对象
- 使用rails高效开发之快速创建控制器 视图 模型和数据库文件
- NGUI使用Scroll View时小圆点的设计
- 使用强类型DataSet创建高效的数据访问层:存储过程输出参数的使用
- NGUI_创建及Label的使用_001
- 在NGUI中高效优化UIScrollView之UIWrapContent的简介以及使用
- NGUI使用教程(2) 使用NGUI创建2D场景并且添加标签和按钮
- 使用rails高效开发之快速创建控制器 视图 模型和数据库文件
- [翻译] 在 ASP.Net 4.0 中使用 QueryExtender 控件创建高效的搜索页面
- NGUI使用教程(2) 使用NGUI创建2D场景而且加入标签和button