[UnityUI]NGUI性能优化之ScrollView
来源:互联网 发布:ubuntu g 安装 编辑:程序博客网 时间:2024/06/05 22:31
使用UIWrapContent优化ScrollView
如上图,虽然显示20个数据,但实际的GameObject只有6个,5个用于显示,1个用于缓存。NGUI中的UIWrapContent.cs通用性不是很好,需要修改一下:
//----------------------------------------------// NGUI: Next-Gen UI kit// Copyright © 2011-2015 Tasharen Entertainment//----------------------------------------------using UnityEngine;using System.Collections.Generic;/// <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 UIWrapContent : MonoBehaviour{public delegate void OnInitializeItem (GameObject go, int wrapIndex, int realIndex);/// <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;/// <summary>/// Minimum allowed index for items. If "min" is equal to "max" then there is no limit./// For vertical scroll views indices increment with the Y position (towards top of the screen)./// </summary>public int minIndex = 0;/// <summary>/// Maximum allowed index for items. If "min" is equal to "max" then there is no limit./// For vertical scroll views indices increment with the Y position (towards top of the screen)./// </summary>public int maxIndex = 0;/// <summary>/// Callback that will be called every time an item needs to have its content updated./// The 'wrapIndex' is the index within the child list, and 'realIndex' is the index using position logic./// </summary>public OnInitializeItem onInitializeItem;Transform mTrans;UIPanel mPanel;UIScrollView mScroll;bool mHorizontal = false;bool mFirstTime = true; List<Transform> mChildren = new List<Transform>(); Vector3 mFirstPos;/// <summary>/// Initialize everything and register a callback with the UIPanel to be notified when the clipping region moves./// </summary>protected virtual void Start (){ if (onInitializeItem == null) onInitializeItem = RefreshItem;SortBasedOnScrollMovement();WrapContent();if (mScroll != null) mScroll.GetComponent<UIPanel>().onClipMove = OnMove;mFirstTime = false;}/// <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 (){ if (mTrans == null) mTrans = transform; if (mPanel == null) mPanel = NGUITools.FindInParents<UIPanel>(gameObject); if (mScroll == null) 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 (){ mFirstPos = mChildren[0].localPosition;for (int i = 0, imax = mChildren.Count; i < imax; ++i){Transform t = mChildren[i]; t.localPosition = mHorizontal ? new Vector3(mFirstPos.x + i * itemSize, mFirstPos.y, 0f) : new Vector3(mFirstPos.x, mFirstPos.y - i * itemSize, 0f);UpdateItem(t, i);}}/// <summary>/// Wrap all content, repositioning all children as needed./// </summary>public void WrapContent (){float extents = itemSize * mChildren.Count * 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);bool allWithinRange = true;float ext2 = extents * 2f;if (mHorizontal){float min = corners[0].x - itemSize;float max = corners[2].x + itemSize;for (int i = 0, imax = mChildren.Count; i < imax; ++i){Transform t = mChildren[i];float distance = t.localPosition.x - center.x;if (distance < -extents){Vector3 pos = t.localPosition;pos.x += ext2;distance = pos.x - center.x;//int realIndex = Mathf.RoundToInt(pos.x / itemSize); int realIndex = Mathf.RoundToInt((pos.x - mFirstPos.x) / itemSize);if (minIndex == maxIndex || (minIndex <= realIndex && realIndex <= maxIndex)){t.localPosition = pos;UpdateItem(t, i);}else allWithinRange = false;}else if (distance > extents){Vector3 pos = t.localPosition;pos.x -= ext2;distance = pos.x - center.x;//int realIndex = Mathf.RoundToInt(pos.x / itemSize); int realIndex = Mathf.RoundToInt((pos.x - mFirstPos.x) / itemSize);if (minIndex == maxIndex || (minIndex <= realIndex && realIndex <= maxIndex)){t.localPosition = pos;UpdateItem(t, i);}else allWithinRange = false;}else if (mFirstTime) 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, imax = mChildren.Count; i < imax; ++i){Transform t = mChildren[i];float distance = t.localPosition.y - center.y;if (distance < -extents){Vector3 pos = t.localPosition;pos.y += ext2;distance = pos.y - center.y;//int realIndex = Mathf.RoundToInt(pos.y / itemSize); int realIndex = Mathf.RoundToInt((mFirstPos.y - pos.y) / itemSize);if (minIndex == maxIndex || (minIndex <= realIndex && realIndex <= maxIndex)){t.localPosition = pos;UpdateItem(t, i);}else allWithinRange = false;}else if (distance > extents){Vector3 pos = t.localPosition;pos.y -= ext2;distance = pos.y - center.y;//int realIndex = Mathf.RoundToInt(pos.y / itemSize); int realIndex = Mathf.RoundToInt((mFirstPos.y - pos.y) / itemSize);if (minIndex == maxIndex || (minIndex <= realIndex && realIndex <= maxIndex)){t.localPosition = pos;UpdateItem(t, i);}else allWithinRange = false;}else if (mFirstTime) 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);}}}mScroll.restrictWithinPanel = !allWithinRange;}/// <summary>/// Sanity checks./// </summary>void OnValidate (){if (maxIndex < minIndex)maxIndex = minIndex;if (minIndex > maxIndex)maxIndex = minIndex;}/// <summary>/// Want to update the content of items as they are scrolled? Override this function./// </summary>protected virtual void UpdateItem (Transform item, int index){if (onInitializeItem != null){int realIndex = (mScroll.movement == UIScrollView.Movement.Vertical) ? Mathf.RoundToInt((mFirstPos.y - item.localPosition.y) / itemSize) : Mathf.RoundToInt((item.localPosition.x - mFirstPos.x) / itemSize);onInitializeItem(item.gameObject, index, realIndex);}} protected virtual void RefreshItem(GameObject go, int wrapIndex, int realIndex) { }}
使用起来也很简单:
using UnityEngine;using System.Collections;public class MyUIWrapContent : UIWrapContent { protected override void RefreshItem(GameObject go, int wrapIndex, int realIndex) { go.transform.FindChild("Label").GetComponent<UILabel>().text = realIndex.ToString(); //Debug.Log(go.name + " " + wrapIndex + " " + realIndex); } }
0 0
- [UnityUI]NGUI性能优化之ScrollView
- NGUI ScrollView优化
- [UnityUI]NGUI备忘录
- [UnityUI]NGUI备忘录
- NGUI之ScrollView
- ngui学习之scrollview
- NGUI UIScrollView UIGrid性能优化
- NGUI性能优化方法总结
- Unity NGUI之ScrollView扩展-1
- Unity NGUI之ScrollView扩展-2
- 优化 scrollView 性能(tableView)
- Unity3D之NGUI的优化
- Unity+NGUI性能优化方法总结
- Unity+NGUI性能优化方法总结
- Unity+NGUI性能优化方法总结
- Unity+NGUI性能优化方法总结
- Unity+NGUI性能优化方法总结
- Unity+NGUI性能优化方法总结
- UNIX环境高级编程(阅读笔记)——线程属性
- 【算法集中营】计算两个日期之间的天数
- PHP、JavaScript、HTML三者的比较
- Java Web前端到后台常用框架介绍
- 直接插入排序的c语言实现
- [UnityUI]NGUI性能优化之ScrollView
- 53-Linked List Cycle II
- 贪心算法☞最优服务次序&多处服务最优次序
- hdu 2328 字符串处理Corporate Identity
- MySQL/Oracle数据库基础
- Java中的自动装箱与拆箱
- 自定义ViewPager指示器
- Google机器学习教程心得(三) 好的feature
- Unix网络编程之常见的数据结构