原因

在使用 Unity 开发游戏的时候,经常会需要用到数据配置,方式可能是CSV、JSON等等。为了可以方便地查看修改数据,通常使用ScrollView实现在 Unity 编辑器里面以列表的形式查看数据。

当数据量大的时候,滚动视图会发现卡顿不断,测试代码如下:

using UnityEditor;
using UnityEngine;public class TestListView : EditorWindow
{[MenuItem("Tool/Test")]private static void Init(){GetWindow<TestListView>();}private const int s_RowCount = 400;private const int s_ColCount = 30;private float m_RowHeight = 18f;private float m_ColWidth = 52f;private Vector2 m_ScrollPosition;void OnGUI(){OnDrawListView2();}private void OnDrawListView(){m_ScrollPosition = EditorGUILayout.BeginScrollView(m_ScrollPosition);for (int i = 0; i < s_RowCount; i++){EditorGUILayout.BeginHorizontal();for (int j = 0; j < s_ColCount; j++){EditorGUILayout.LabelField((i * 100 + j).ToString(), GUILayout.Width(m_ColWidth));}EditorGUILayout.EndHorizontal();}EditorGUILayout.EndScrollView();}
}

鼠标拖动滚动条滚动的时候,可以明显发现滚动条卡顿延迟跟着鼠标动:

解决

优化的思路就是只绘制当前可视的区域,自 Unity 5.6 开始已经提供TreeView控件,自带支持大数据集,
详见https://docs.unity3d.com/560/Documentation/ScriptReference/IMGUI.Controls.TreeView.BuildRoot.html

如果还没使用 Unity 5.6,那么可以参考它的实现方式。将Layout自动布局方式改成给定矩形来绘制,这样方便知道每行的高度和总的内容高度,再根据滚动条的坐标来计算获取当前显示的起始行和结束行,只绘制需要显示的行内容。

代码修改如下:

using UnityEditor;
using UnityEngine;public class TestListView : EditorWindow
{[MenuItem("Tool/Test")]private static void Init(){GetWindow<TestListView>();}private const int s_RowCount = 400;private const int s_ColCount = 30;private float m_RowHeight = 18f;private float m_ColWidth = 52f;private Vector2 m_ScrollPosition;void OnGUI(){OnDrawListView2();}private void OnDrawListView2(){Rect totalRect = new Rect(0, 0, position.width, position.height);Rect contentRect = new Rect(0, 0, s_ColCount * m_ColWidth, s_RowCount * m_RowHeight);m_ScrollPosition = GUI.BeginScrollView(totalRect, m_ScrollPosition, contentRect);int num;int num2;GetFirstAndLastRowVisible(out num, out num2, totalRect.height);if (num2 >= 0){int numVisibleRows = num2 - num + 1;IterateVisibleItems(num, numVisibleRows, contentRect.width, totalRect.height);}GUI.EndScrollView(true);}/// <summary>/// 获取可显示的起始行和结束行/// </summary>/// <param name="firstRowVisible">起始行</param>/// <param name="lastRowVisible">结束行</param>/// <param name="viewHeight">视图高度</param>private void GetFirstAndLastRowVisible(out int firstRowVisible, out int lastRowVisible, float viewHeight){if (s_RowCount == 0){firstRowVisible = lastRowVisible = -1;}else{float y = m_ScrollPosition.y;float height = viewHeight;firstRowVisible = (int)Mathf.Floor(y / m_RowHeight);lastRowVisible = firstRowVisible + (int)Mathf.Ceil(height / m_RowHeight);firstRowVisible = Mathf.Max(firstRowVisible, 0);lastRowVisible = Mathf.Min(lastRowVisible, s_RowCount - 1);if (firstRowVisible >= s_RowCount && firstRowVisible > 0){m_ScrollPosition.y = 0f;GetFirstAndLastRowVisible(out firstRowVisible, out lastRowVisible, viewHeight);}}}/// <summary>/// 迭代绘制可显示的项/// </summary>/// <param name="firstRow">起始行</param>/// <param name="numVisibleRows">总可显示行数</param>/// <param name="rowWidth">每行的宽度</param>/// <param name="viewHeight">视图高度</param>private void IterateVisibleItems(int firstRow, int numVisibleRows, float rowWidth, float viewHeight){int i = 0;while (i < numVisibleRows){int num2 = firstRow + i;Rect rowRect = new Rect(0f, (float)num2 * m_RowHeight, rowWidth, m_RowHeight);float num3 = rowRect.y - m_ScrollPosition.y;if (num3 <= viewHeight){Rect colRect = new Rect(rowRect);colRect.width = m_ColWidth;for (int j = 0; j < s_ColCount; j++){EditorGUI.LabelField(colRect, (num2 * 100 + j).ToString());colRect.x += colRect.width;}}i++;}}
}

再次鼠标拖动滚动条滚动的时候,可以明显发现滚动条流畅许多:

编辑时的问题

因为不是绘制全部控件,那么当使用编辑框的时候,弹出的编辑控件不会跟随着滚动,如下所示:

那么就当滚动的时候,结束当前正在编辑的项吧,修改OnDrawListView2函数:

    private void OnDrawListView2(){Rect totalRect = new Rect(0, 0, position.width, position.height);Rect contentRect = new Rect(0, 0, s_ColCount * m_ColWidth, s_RowCount * m_RowHeight);// 鼠标滚动的时候,结束当前正在编辑的项if (Event.current.type == EventType.ScrollWheel){if (totalRect.Contains(Event.current.mousePosition)){GUIUtility.keyboardControl = 0;}}EditorGUI.BeginChangeCheck();m_ScrollPosition = GUI.BeginScrollView(totalRect, m_ScrollPosition, contentRect);if (EditorGUI.EndChangeCheck()){// 滚动条滚动的时候,结束当前正在编辑的项GUIUtility.keyboardControl = 0;}int num;int num2;GetFirstAndLastRowVisible(out num, out num2, totalRect.height);if (num2 >= 0){int numVisibleRows = num2 - num + 1;IterateVisibleItems(num, numVisibleRows, contentRect.width, totalRect.height);}GUI.EndScrollView(true);}

自动布局

如果还是想使用自动布局方式来绘制项的话,那么可以使用GUILayout.Space来占用不需要绘制的区域。

Unity 编辑器ScrollView滚动卡顿优化相关推荐

  1. 关于图片解压缩,导致scrollView滚动卡顿

    可以看出在开发的时候,如果scrollView中有很多图片,那么在拖动的过程中,会有明显的卡顿,这是因为每次显示一个UIImageView的时候都需要将图片文件解压缩并渲染到屏幕上这一系列工作上,然而 ...

  2. Android 性能优化(62)---存检测、卡顿优化、耗电优化、APK瘦身——详解篇

    Android 性能优化,内存检测.卡顿优化.耗电优化.APK瘦身--详解篇 自2008年智能时代开始,Android操作系统一路高歌,10年智能机发展之路,如今 Android 9.0 代号P  都 ...

  3. bootsrtap h5 移动版页面 在苹果手机ios滑动上下拉动滚动卡顿问题解决方法

    bootsrtap h5 移动版页面 在苹果手机ios滑动上下拉动滚动卡顿问题解决方法 bootsrtap框架做的h5页面,在android手机下没有卡顿问题,在苹果手机就一直存在这问题,开始毫无头绪 ...

  4. scum开服务器延迟高怎么办,人渣SCUM卡顿优化方法 人渣SCUM卡顿怎么办

    人渣SCUM卡顿优化方法 人渣SCUM卡顿怎么办 2018-09-05 09:32:15来源:SCUM吧/fabulis编辑:野狐禅评论(0) <人渣SCUM>卡顿不流畅怎么优化呢?不少玩 ...

  5. 深入探索Android卡顿优化(下)

    前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~. 在上篇文章中,笔者带领大家学习了卡顿优化分析方法与工具.自动化卡顿检测方案及优化这两块内容. ...

  6. Android 卡顿优化之 Skipped * frames 掉帧的计算

    Android 卡顿优化之 Skipped * frames 掉帧的计算 有时候看日志的时候,可能会在日志中看到类似下文的打印: Skipped 30 frames! The application ...

  7. 深入探索Android卡顿优化

    由于卡顿优化这一主题包含的内容太多,为了更详细地进行讲解,因此,笔者将它分为了上.下两篇.本篇,即为<深入探索Android卡顿优化>的上篇. 本篇包含的主要内容如下所示: 卡顿优化分析方 ...

  8. 微信小程序scroll-view滑动卡顿,下滑时向上滑动失效

    微信小程序scroll-view滑动卡顿 滑动卡顿 解决方案 代码实现 wxml文件 js文件 滑动卡顿 微信小程序scroll-view组件在滑动时频繁卡顿,向下滑动时,向上滑动无效,无法停止.小程 ...

  9. Android性能优化系列篇(三):崩溃优化+卡顿优化

    前言 汇总了一下众多大佬的性能优化文章,知识点,主要包含: UI优化/启动优化/崩溃优化/卡顿优化/安全性优化/弱网优化/APP深度优化等等等~ 本篇是第三篇:崩溃优化+卡顿优化 [非商业用途,如有侵 ...

最新文章

  1. mysql 查询结果行变列_SQL 查询怎么将行变成列
  2. codeblocks如何watch数组
  3. 2的32次方减1用python,第二章python入门
  4. spark 架构_深入研究Spark内部和架构
  5. AAA验证和ciscorescue v4.2 验证服务器的搭建(telnet方式和级别的设置)
  6. 简单的redis使用watch完成秒杀抢购功能
  7. JAVA使用bean配置ftp_FTP文件上传(By)java
  8. JAVA汽车4s店管理系统前后台
  9. matlab计算并联电阻怎么输入,如何用计算器快速计算并联电阻,并联电阻的计算方法...
  10. PCB_问题记录_QT(1)引用gdiplus.h、Gdiplus.lib 报错
  11. 终于搞懂了回车与换行的区别
  12. 平板电脑可以用手写的计算机软件,平板电脑可以当手写板(绘图板)用吗?
  13. 如何汇总100多个相同模板的电子表格
  14. 计算机应用能力 中文字处理,职称计算机Word 2003中文字处理考试大纲
  15. linux网卡桥接模式无法上网
  16. 基于物联网流量指纹的安全威胁轻量级检测方法
  17. 计算机一级ppt定位,课件全国计算机一级基础知识.ppt
  18. Bseline基准预测、zip()、dict()、groupy().agg()、
  19. 《商用密码应用与安全性评估》第二章政策法规2.2法律法规
  20. linux禁用触控板驱动程序,linux – X11 EvDev触摸屏驱动程序:禁用长按在桌面上单击鼠标右键...

热门文章

  1. 关于定时器、波特率、TH和TL值的计算
  2. WIN32 消息总结
  3. 算法书籍推荐及网络资源
  4. CEAC之《职业素养》
  5. C#字符串转换成数字 ,使用方法TryParse
  6. Excel插件工具箱-Kutools for Excel v26 学习版免费下载
  7. 多巴胺ELISA试剂盒方案:体外定量,手动操作
  8. 计算机更新要联网吗,Steam需要在线进行更新,请确认您的网络连接正常的解决方法...
  9. android实现打卡功能,android实现上班打卡记录日历查看功能
  10. Vercel(zeit)自定义404.html页面