UGUI Scroll Rect 加载大量Item 优化
开发环境:win7 64位 Unity 5.1
和NGUI 一样 UGUI后期优化都要自己去实现。
Scroll Rect(Scroll View) 大量加载Item时,卡顿严重,接下来让我们简单粗暴的优化吧。
1.分析原因-为啥大量加载会卡顿?
NGUI中UIPanel裁剪 和UGUI中的Mask 遮罩一样,组件在视界外虽然不显示但还是参与了渲染工作。
有渲染就要消耗 Batches(Draw Call) 这样的设定吾辈无法接受。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DMygzM1ITN1EjNxcDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
2.解决问题。
获取scrollrect视界大小 和item大小,再计算出我们需要对象渲染的范围,超出这个范围我们就让它停止渲染(不是mask的遮罩)。
3.代码实现优化
Item结构
<span style="font-size:14px;">public class AchieveManage : MonoBehaviour
{
public ScrollRect scroRect; //ScrollRect
public VerticalLayoutGroup group; //VerticalLayoutGroup
public GameObject prefab_item; //预设
public int maxCount = 200; //生产 数量
List<GameObject> list;
float scroRect_MinHight; //预设高度
float scroRect_MaxHight; //scrollrect 视图高度
void Start()
{
//1.计算出 scrollrect 视图范围
scroRect_MinHight = prefab_item.GetComponent<LayoutElement>().preferredHeight; //获取预设高度
scroRect_MaxHight = scroRect.transform.position.y + scroRect_MinHight; //获取scrollrect 视图高度
list = new List<GameObject>();
CreateAchieve(); //创建成就
StartCoroutine(IEShowInit()); //隐藏初始化
}
//创建成就
void CreateAchieve()
{
for (int i = 0; i < maxCount; i++)
{
var go = Instantiate(prefab_item) as GameObject;
go.SetActive(true);
go.transform.position = Vector3.zero;
go.transform.SetParent(group.transform);
go.name = "item" + i;
go.transform.FindChild("msg/txt1").GetComponent<Text>().text = go.name;
list.Add(go);
}
}
//2.拖动完毕委托事件
public void VCValueChanged()
{
list.ForEach((p) =>{CheckPos(p.transform);});
}
//3.检测 在scrollrect 视图内
void CheckPos(Transform obj)
{
var pos = obj.position;
var go = obj.gameObject;
if (pos.y >= -scroRect_MinHight && pos.y <=scroRect_MaxHight)
ShowItem(go);
else
HideItem(go);
}
//4.隐藏或显示
void ShowItem(GameObject go)
{
go.transform.GetComponent<Image>().enabled = true;
go.transform.FindChild("sprite").gameObject.SetActive(true);
go.transform.FindChild("msg").gameObject.SetActive(true);
go.transform.FindChild("but").gameObject.SetActive(true);
}
void HideItem(GameObject go)
{
go.transform.GetComponent<Image>().enabled = false;
go.transform.FindChild("sprite").gameObject.SetActive(false);
go.transform.FindChild("msg").gameObject.SetActive(false);
go.transform.FindChild("but").gameObject.SetActive(false);
}
IEnumerator IEShowInit()
{
yield return new WaitForSeconds(0.3f);
VCValueChanged();
}
}</span>
4.调用测试,生成200Item batch 只有 60 ,如果没有优化瞬间飙到1K多....
NGUI 的scroll view优化也是这思路。
高能:此方法分分钟更改成动态加载。