使用NGUI 3.5.5创建高效的超大Scroll View
来源:互联网 发布:绝地求生优化太差 编辑:程序博客网 时间:2024/05/21 07:42
在使用NGUI的Scroll View的时候,碰到Scroll Item太多的话(超过100个),在滑动的过程中就会明显掉帧。究其原因就是NGUI每帧会对所有的Scroll Item进行更新,无论它是否显示。
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.csmScroll.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.csmBounds = NGUIMath.CalculateRelativeWidgetBounds(mTrans, mTrans);
修改后的代码如下:// line 173, file: UIBetterGrid.csmBounds = 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 ordermChildren.Clear();for (int i = 0; i < mTrans.childCount; ++i)mChildren.Add(mTrans.GetChild(i));// Sort the list of children so that they are in orderif (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 ordermChildren.Clear();for (int i = 0; i < mTrans.childCount; ++i)mChildren.Add(mTrans.GetChild(i));// Sort the list of children so that they are in ordermChildren.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提供好文章
0 0
- 使用NGUI 3.5.5创建高效的超大Scroll View
- 使用NGUI 3.5.5创建高效的超大Scroll View
- NGUI创建Scroll View的基本步骤
- NGUI 3.0 Scroll View的使用
- NGUI使用Scroll View时小圆点的设计
- 【Unity&NGUI】创建NGUI的Scroll View的一些问题以及拓展
- NGUI的Scroll View的制作
- 如何制作NGUI的Scroll View
- NGUI -- Scroll View
- 【NGUI】循环Scroll View
- NGUI之Scroll View
- Unity3D NGUI Scroll View注意事项
- 【Unity3D】【NGUI】循环Scroll View
- NGUI 例子8 scroll view
- NGUI Scroll View 循环滚动
- Unity NGUI制作scroll view
- unity NGUI tutorial scroll view
- Unity3D NGUI Scroll View注意事项
- 一点一点学xamarin.forms
- 第十四周OJ项目1-求矩阵对角线元素之和
- PowerCenter 使用日记
- 编程练习:Transmitters
- 五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT)
- 使用NGUI 3.5.5创建高效的超大Scroll View
- ActionContext和ServletActionContext小结
- linux下进程间共享内存通信的问题
- Eclipse Tomcat配置/管理/调试指南
- Hduoj1312【广搜】
- SEL(去除警告)、Block(block深入研究、block回调--匿名函数)
- MACHINE_START-内核板级初始化实现机制(linux3.1.0)
- CascadeClassifier中MaskGenerator的含义与用法
- R: 矩阵运算及常用函数 I - split