在Unity做性能优化,或者做一些编辑器工具的时候,如果把收集回来的数据用图表来展示,可以使数据更加直观,如果是性能优化的时候,就能更突显出问题所在。

在项目的开发过程中有同事做了个可视化工具,看了一下真实高端,就研究了一下并且简化做了个demo。

所以这其实也不能算原创,更多的代码是同事写的,我只能算是介绍了一下代码逻辑和实现原理。


首先看下效果:

【unity系统模块开发】UnityEditor工具--数据可视化_第1张图片

这个是我简化过的版本,数据是在一定范围内随机的,看起来也还可以。

横轴是时间,纵轴是数量。不同颜色区域代表不同数据。点击每帧的时候出现每帧具体数据


接下来就是讲具体实现.


这里面有几部分:

  1. 数据收集

  2. 数据可视化

  3. 点中具体位置时显示当前位置的具体数据。




1.数据收集

首先这里的数据收集就看你的需求,是做一个性能检测工具的话,就收集drawcall信息。做玩家数据分析就收集玩家数据。


在我们这个demo中,可以看到上面每帧中有4组数据(Data1,Data2,Data3,Data4),每个数据类型都是int,可以当做是次数收集。

也就是说,我们每帧去获取这四个数据,把四个数据放在同一个结构里,然后这个结构放在一个list里。

【unity系统模块开发】UnityEditor工具--数据可视化_第2张图片

我因为只是做个demo,所以数据就模拟生成了。

【unity系统模块开发】UnityEditor工具--数据可视化_第3张图片

可以看到。为了显示的时候直观一点,我把随机区域稍微区分了一下,这样看起来好看点,像第一个图那样。



2.数据可视化

接下来就讲一讲怎么把这些数据转换成图表。

【unity系统模块开发】UnityEditor工具--数据可视化_第4张图片

这里面可以拆成几部分来看

  1. xy轴

  2. 数据图

  3. 定位线

  4. 总数据文本

  5. 当前帧数据文本


我们是在OnGUI()里面去实现画图,也就是说,在每个OnGUI的update里,这5个部分都需要绘制。

接下来就一个个说。


  1. xy轴

    xy轴很简单,就是在固定位置画两个带箭头的线,带箭头的线这个在上篇文章就有给代码,所以这里就不多说了。

    具体就看上篇文章:https://blog.51cto.com/13638120/2103459

  2. 数据图

    这部分是整篇文章的重点,因为数据收集只是收集个数记录,要把个数转成图表还是有点麻烦的。

    首先基本概念是,既然是画图,就是画三角形,既然是画三角形,就是把坐标信息传到GL.Vertex()里绘制,所以说到底就是把个数转换成坐标,画的是个二维图,所以z轴统一为0.也就是要获取x,y坐标。

    画三角形也有有两种方式,TRIANGLES和TRIANGLE_STRIP,这部分前者是每三个坐标画一个三角形,两个三角形要6个坐标。后者是前三个坐标画第一个三角形,第四个坐标和第二三个坐标组成三个坐标,画第二个三角形。

    这部分如果不理解的话看下这篇文章:https://blog.csdn.net/onafioo/article/details/39454233

    而对于我们来说,我们需要的是做到像上面的图一样,填满图表,所以选择第二种TRIANGLE_STRIP会更会合适且容易实现。比如:

    【unity系统模块开发】UnityEditor工具--数据可视化_第5张图片【unity系统模块开发】UnityEditor工具--数据可视化_第6张图片

    上面标了ABCD四个点,这四个点之间的这片区域就通过这四个点就可以画满,ABC构成第一个三角形,CBD构成第二个三角形。这时只要把ABCD这四个点依次传入就可以了。

    所以接下来要解决的就是怎么得出坐标。

    先看一下代码:

       【unity系统模块开发】UnityEditor工具--数据可视化_第7张图片

    _graphContentRect是这个绘图框的Rect。

    首先,x坐标是很好计算的。算法就是以这个Rect的左边框为第一个点,计算当前点占总共点个数的第几个,再乘以这个Rect的宽,再加上左边的一个点的x坐标得到当前点坐标。

    y坐标的计算方法就是,首先需要知道所有点的最高值是多少,因为y坐标代表的是个数,这个值是不固定的,所有需要每帧去算最大值是多少。然后算法就跟上面算x差不多,算出当前的个数占最高值的多少,乘以这个Rect高,用这个Rect最高点坐标减去这个坐标活动y坐标。

    这样就获得这个点的绘制坐标了。

    有了坐标就开始画三角形,按照上面的说法,就是按ABCD坐标顺序把点塞到GL.Vertex()里。

【unity系统模块开发】UnityEditor工具--数据可视化_第8张图片

先不看中间的ifelse判断,先省略if的情况。可以看到,比如说画Data1的图(一开始的图的×××部分),就是把当前帧Data1的点,和Data2的点传进去,再传第二帧Data1的点和Data2的点。跟我们上面说的ABCD是一样的。

其他颜色块的画法以此类推。

只不过到最下面的时候,也就是上面的if里面的代码块,y坐标就取y轴的坐标 _graphContentRect.yMax,完成。


到这里就完成了画图了。

现在可以看看效果:

【unity系统模块开发】UnityEditor工具--数据可视化_第9张图片

这里会有明显的锯齿,想着优化一下的话,给描个边,消一下锯齿。

【unity系统模块开发】UnityEditor工具--数据可视化_第10张图片

【unity系统模块开发】UnityEditor工具--数据可视化_第11张图片

这下真的好了~


3.定位线

    也就是根据你选择的点,找到那个点的最高值坐标,在那个左边的左方向和上下方向画线。

image.png

4.总数据文本

    比较简单,具体就看代码好了

5.当前帧数据文本

    比较简单,具体就看代码好了


第二部分的数据可视化就讲完了~~~


3.点中具体位置时显示当前位置的具体数据。

    就是监听一下鼠标点击事件,根据鼠标点中的位置判断距离它最近的坐标,获取数据。

【unity系统模块开发】UnityEditor工具--数据可视化_第12张图片


这里就讲完所有的了。

下面提供Demo,还有不懂的可以看代码或者留言交流~

https://pan.baidu.com/s/1w65S-J_qg2_w2CUzuB_B0Q