h5页面的雷达图 五边形_属性雷达图UGUI渲染器

19ced7eee2c27bcfb246aa4a142b53cb.png

【博物纳新】是UWA旨在为开发者推荐新颖、易用、有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目、前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项目的可行性。很多时候,我们并不知道自己想要什么,直到某一天我们遇到了它。

更多精彩内容请关注:lab.uwa4d.com


导读

在许多游戏会使用雷达图展示角色的各个属性值大小。这是一种较为常见的UI界面。

dcf1ae14c1278e869121148ebb7f980b.png
MMORPG手游《仙境传说RO:守护永恒的爱》中创建角色页面

开源库项目UI Polygon采用拓展UGUI组件的方式,构建边长可调节的多边形UI组件。可用于实现雷达图效果。

2beb30b4dcbed74c481b42f5ea80f802.png
效果图

作者Blog:http://ciaccodavi.de/

开源库链接:https://lab.uwa4d.com/lab/5b5d1083d7f10a201fea7299


使用方法

使用方法十分简单。首先将项目中的“UIPolygon.cs”文件导入Unity工程,在工程中的UI组件Canvas下Create Empty。

bc7c1636e234a6967b7e00bb4049d41d.png

接着给这个空物体添加“UIPolygon.cs”组件:

2c2b154c4e4a2a486c28fdfc686aee7a.png

最后调节属性,实现需要的效果。例如:是否空心、旋转角度、多边形边数、凹凸程度等。

b355b42f8f17eb80135934de5ec6b8ed.gif

1e9dd1bb58dda2218746357907ec08b2.gif

80b67e5580250706cb3ee487209cdee6.gif

658c58bca25d1073f714b3aea0b4820e.gif

实现方式

Unity官方发布了部分UGUI的源码(下载地址:https://bitbucket.org/Unity-Technologies/ui/downloads/?tab=downloads),通过对源码的阅读,可以帮助我们拓展实现更多的UI功能。

该开源库项目便是创建了一个继承自MaskableGraphic的类UIPolygon,实现了上述效果。

MaskableGraphic类是UGUI的核心组件,继承自Graphic,是一个抽象类,它的派生类有RawImage、Image、Text等。在这里不做详细说明,有兴趣的读者,推荐阅读由凯奥斯撰写的UGUI内核大探究系列,关于MaskableGraphic的一篇:https://blog.csdn.net/ecidevilin/article/details/52555253

首先在Update()函数中确定组件大小长度变量size,等于该GameObject长宽的较小值;确定镂空时,镂空部分的长度不能超过size的一半。

void Update()
{
  size = rectTransform.rect.width;
  if (rectTransform.rect.width > rectTransform.rect.height)
    size = rectTransform.rect.height;
  else
    size = rectTransform.rect.width;
  thickness = (float)Mathf.Clamp(thickness, 0, size / 2);
}

接着继承虚函数OnPopulateMesh(VertexHelper vh),并重写绘制逻辑。OnPopulateMesh函数用于收集Mesh信息,在具体的类中各自实现。VertexHelper类保存了Mesh的基本信息,通过这些信息构成Mesh网络。它的成员函数AddUIVertexQuad用于保存一个四边形的基本Mesh信息。四边形是Unity中UI绘制的一个基本图元:

585af35b8cbd8e382cc0e82bccd6ad8e.png
四边形图元

这部分内容不再详细描述,有兴趣的读者,推荐阅读由宣雨松撰写的《UGUI深度研究之源码鉴赏》,其中有较为详细的解析。

以网格锚点pivot.xy=(0.5,0.5)的五边形为例,对于一个五边形来说,实际是绘制了六个四边形。

在不镂空的情况下:

61c7ad5c389825d3822ea54d30b035d5.png

设定两个变量默认在中心点O:

Vector2 prevX = Vector2.zero;
Vector2 prevY = Vector2.zero;

绘制第一个四边形,四个顶点pos0~3分别为[O,A,O,O],其中A点位置根据用户在面板上设定的百分比、锚点位置、size大小、旋转角度等进行计算:

float degrees = 360f / sides;
float outer = -rectTransform.pivot.x * size * VerticesDistances[i];
float rad = Mathf.Deg2Rad * (i * degrees + rotation);
float c = Mathf.Cos(rad);
float s = Mathf.Sin(rad);
pos1 = new Vector2(outer * c, outer * s);

对于A点的坐标即为(size*0.5*1,0),第一个四边形等同于没有绘制,主要用途是计算A点位置。

保存pos1和pos2的位置:

pos0 = prevX;
pos1 = new Vector2(outer * c, outer * s);
pos2 = Vector2.zero;
pos3 = Vector2.zero;
prevX = pos1;
prevY = pos2;
vh.AddUIVertexQuad(SetVbo(new[] { pos0, pos1, pos2, pos3 }, new[] { uv0, uv1, uv2, uv3 }));

然后,绘制第二个四边形,四个顶点pos0~3分别为:[A,B,O,O],剩余的四边形同理。

对于镂空的情况:

91baead85673ebfe9762748278986a4c.png

依次绘制四边形[A,B,A,A]、[A,B,C,D]等等,顶点位置的计算与上述方式相似:

float inner = -rectTransform.pivot.x * size * VerticesDistances[i] + thickness;
pos2 = new Vector2(inner * c, inner * s);
pos3 = prevY;

最后提供一些重载的绘制接口,可以在程序中动态调用:

public void DrawPolygon(int _sides)
{
  sides = _sides;
  VerticesDistances = new float[_sides + 1];
  for (int i = 0; i < _sides; i++) VerticesDistances[i] = 1;
  rotation = 0;
}
public void DrawPolygon(int _sides, float[] _VerticesDistances)
{
  sides = _sides;
  VerticesDistances = _VerticesDistances;
  rotation = 0;
}
public void DrawPolygon(int _sides, float[] _VerticesDistances, float _rotation)
{
  sides = _sides;
  VerticesDistances = _VerticesDistances;
  rotation = _rotation;
}

性能测评

fdbd79f8514a9bb702fa63457ec7f12c.png

使用Profiler查看UI的DrawCall与Batch情况,可以看到,使用该组件会产生一个DrawCall并且满足UGUI的合批规则。

通过脚本每帧更改多边形颜色,重绘该多边形界面,通过UWA GOT Online测试Mono堆内存的分配:

cc51fe5ea58e8a87137184662ab77eb0.png

可见堆内存分配稍高,针对这样的现象我们可以针对SetVbo()函数的局部变量vbo进行处理:

UIVertex[] vbo = new UIVertex[4];

将vbo变量设置为该类的成员变量。Mono堆内存分配就会小很多:

be26a42bc561088022ac3d1e413f75e4.png

快用UWA Lab合辑Mark好项目!

7b92eb93fd0e563ae82113f0f4fef67d.gif

今天的推荐就到这儿啦,或者它可直接使用,或者它需要您的润色,或者它启发了您的思路......

请不要吝啬您的点赞和转发,让我们知道我们在做对的事。当然如果您可以留言给出宝贵的意见,我们会越做越好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值