发布时间:2017-05-24责任编辑:朱明 浏览:6234
现手游项目中使用了大量的滚动层,但滚动层使用不慎,就给给项目带来困扰,尤其是面对需要加载大量数据的子部件时,在滑动过程中难免会有卡顿现象,接下来讲一下自己使用scrollRect时,需要加载大量子部件时的方法,供大家参考,大家有更好的建议欢迎一起探讨。
图片是项目中的英雄列表,它使用了scrollRect 加载了很多英雄,每个英雄上包含了多重信息。

scrollRect 加载大量子部件后,滑动 scrollRect 过程中,引擎会同时计算所有子部件的位置信息,如果子部件上包含N个子子部件,那么他的计算量便是普通的N倍,如下面两图对比,每一条黑色的线,便是一个需要计算的点,第三张图可以看出下面所有的子部件,都显示在引擎中。
本方法就是实现减少计算量,简单原理是,首先给子部件增加一个占位部件,也就是当该部件需要展示时,在占位部件上加载该部件,当滑动到隐藏位置时,将该部件从占位上移除,这样在看不到的地方只会有空的占位参与位置计算,计算消耗必然下降,需要的内存也会减少。
话不多说,上代码。
//列表中添加英雄
public void ShowHeros(List<ServerPlayerHero> listHeros)
{
for (int i = listHeros.Count - 1; i >= 0; i--)
{
//创建占位
GameObject go = uiHandler.AddItem(listHeroRoot, heroItemBox);
var item = go.GetComponent<HeroItemViewBox>();
//初始化占位英雄信息
item.Set(listHeros[i]);
//给占位增加位置移动监听
scrollRect.onValueChanged.AddListener(item.MoveChanged);
}
}
//位置监听
public void MoveChanged(Vector2 position)
{
//判断当前位置是否在可视范围内,数值可以自行调节。
bool isfanwei = transform.position.y < 0.3 && transform.position.y > -0.8;
//isShow指的是当前是否在显示状态
if (isShow && !isfanwei)
removeHero();//移除子部件
else (!isShow && isfanwei)
ShowHero();//添加子部件
}
个人在移除子部件和添加子部件时加入了缓存池,使其效率更高。
//展示该角色
public void ShowHero()
{
heroitem = pool.Pop(heroItem);//缓存池中取出item
if (heroitem == null) return;
isShow = true;
heroitem.transform.SetParent(transform);
heroitem.transform.localScale = new UnityEngine.Vector3(1, 1, 1);
heroitem.transform.localPosition = Vector3.zero;
heroitem.Set(heroMsg);
}
//移除该角色
void removeHero()
{
isShow = false;
pool.Push(heroitem);//放入到缓存池中
heroitem = null;
}
//缓存池
public class HeroItemPool : IHeroItemPool
{
//私有的list,保存未被使用的item
private Stack<HeroItemView> listItems = new Stack<HeroItemView>();//缓存列表
public HeroItemView Pop(GameObject prefab)
{
//当list中没有item时,创建一个新的
if (listItems.Count == 0)
{
GameObject go = GameObject.Instantiate<GameObject>(prefab);
listItems.Push(go.GetComponent<HeroItemView>());
}
return listItems.Pop();
}
public void Push(HeroItemView t)
{
//当list中数量大于12时,移除,因为他应该不会用到了
if (listItems.Count < 12)
{
listItems.Push(t);
t.transform.SetParent(null);
}
else {
GameObject.DestroyImmediate(t.gameObject);
}
}
}
战国工作室 供稿