前言

UGUI的ScrollRect加载太多物体的时候,第一次弹出界面会非常卡顿,而且不在界面里的内容依然会参与绘制,产生性能毫无意义的浪费,比如大背包,聊天内容展示等等

这里先记录整理,后面用到了在写写详细的使用

插件

插件可以通过github进行下载,链接是:
https://github.com/qiankanglai/LoopScrollRect

中文文档

https://qiankanglai.me/2015/08/15/LoopScrollRect/

导入插件

把这个链接复制到Package Manager中进行中进行导入:
https://github.com/qiankanglai/LoopScrollRect.git
在这里插入图片描述

查看LoopScrollRect的案例

如果你导入插件成功,点击DemoScene进入演示场景,找到多行多列,上下滚动的案例。
在这里插入图片描述
在这里插入图片描述

使用

可以在Inspector中看到他身上挂着一个脚本:
在这里插入图片描述
这个脚本就是用来初始化滚动容器的核心,我们新创建一个自己的脚本,把InitOnStart中的代码抄过来,然后改成自己的。我命名为:PackageScroll.cs

脚本中的几个要点:

  1. Start函数中对LoopScrollRect进行初始化,唯一需要修改的是ls.totalCount,改成自己的物品总量即可。

  2. ProvideData:实现LoopScrollDataSource接口,子物体从这里拿到数据来刷新自身

  3. 其他可以保持案例中的代码不变,GetObject和ReturnObject实现了一个类似对象池的缓存功能。

using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;

namespace Demo
{
    [RequireComponent(typeof(UnityEngine.UI.LoopScrollRect))]
    [DisallowMultipleComponent]
    public class PackageScroll : MonoBehaviour, LoopScrollPrefabSource, LoopScrollDataSource
    {
        public GameObject item;
        public int totalCount = -1;

        // Implement your own Cache Pool here. The following is just for example.
        Stack<Transform> pool = new Stack<Transform>();
        public GameObject GetObject(int index)
        {
            if (pool.Count == 0)
            {
                return Instantiate(item);
            }
            Transform candidate = pool.Pop();
            candidate.gameObject.SetActive(true);
            return candidate.gameObject;
        }

        public void ReturnObject(Transform trans)
        {
            // Use `DestroyImmediate` here if you don't need Pool
            trans.SendMessage("ScrollCellReturn", SendMessageOptions.DontRequireReceiver);
            trans.gameObject.SetActive(false);
            trans.SetParent(transform, false);
            pool.Push(trans);
        }

        public void ProvideData(Transform transform, int idx)
        {
            List<PackageLocalItem> items = GameManager.Instance.GetSortPackageLocalData();
            PackagePanel uiParent = (PackagePanel)UIManager.Instance.GetPanel(UIConst.PackagePanel);
            transform.GetComponent<PackageCell>().Refresh(items[idx], uiParent);
        }

        void Start()
        {
            var ls = GetComponent<LoopScrollRect>();
            ls.prefabSource = this;
            ls.dataSource = this;
            ls.totalCount = GameManager.Instance.GetSortPackageLocalData().Count;
            ls.RefillCells();
        }
    }
} 

然后把这个脚本挂到VerticalScroll_Grid物体身上,把原本demo中的InitOnStart脚本删了。

因为咱们的背包界面是从预制件中动态创建的,因此需要把VerticalScroll_Grid拷贝到PackagePanel中(替换原本的ScrollView)
在这里插入图片描述
PackagePanel.cs是背包系统界面的主要代码,这里咱们把对原版scrollView初始化的逻辑注释掉,这样之前的滚动容器相当于失效了。
在这里插入图片描述
最后解决第二个问题,根据官方文档,子物体需要做下小小的调整。

加上 Layout Element 这个组件,用来控制子物体的大小,其他都不用改。
在这里插入图片描述
这时候运行游戏就可以看到,我们项目中的滚动容器已经替换为 LoopScrollView
在这里插入图片描述
一些大小和间距可以在这里调整

外层容器的大小:
在这里插入图片描述
内层容器的大小
在这里插入图片描述

参考

https://www.bilibili.com/video/BV1rw4m1e7Rh/?spm_id_from=333.337.search-card.all.click

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐