unity 3d物体描边效果_Unity 实现带均匀描边的雷达图

703645c69444532f8082bd73d74869fa.png

前言

雷达图是游戏中常见的图表表现之一,比如用来呈现英雄的属性等等,本文将在 Unity 中实现一个带均匀描边可响应点击的雷达图。

Graphic类

Unity 的原生 UI 系统 UGUI 提供了名为 Graphic 的基类用于实现各自 UI组件的。该类中有名为 OnPopulateMesh 的方法,只要向参数 VertexHelper 传递正确的顶点数组与下标数组,即可构造出我们期望的网格。

网格的构建

雷达图可以视为一个正多边形各个顶点沿着径向缩放得到,因此我们只要遍历一遍各个角度并且根据当前角度的权重计算就能得到对应的顶点,最后构造下标数组,即可得到所需网格。构造顶点代码如下

b2a32f4ce25e634abd04e6ee8b3730b2.png

这样对于边数为 N 的雷达图,我们会得到包括中心点在内的 N + 1 个顶点,然后是构造下标数组,代码如下。

0f6da2f18e143c28ad5805eb2b6f58ed.png

只是简单地把相邻的顶点两两与中心点组合成三角形,注意这里最后复用了第一个顶点。

响应点击

Unity 的 UI 组件,响应点击需要实现接口 ICanvasRaycastFilter 的 IsRaycastLocationValid 方法。如果命中多边形,也就是点击坐标落在多边形内,则返回 true ,否则返回 false。首先需要将方法参数里的屏幕坐标转换到ui的局部坐标。

6b940c6f0cf5db89277710990e7d3850.png

然后检测坐标是否落在多边形内,对于点击的坐标,我们检测从它出发发射一条指向多边形外的某个顶点的射线,对于多边形的每一条边,检测是否相交,最后统计相交的边的数目,如果为奇数,则代表该点落在多边形内,否则落在多边形外。更多详情可以参考下面的问题。

一个线条自交叉的封闭图形,怎样判断一个点位于图形内部还是外部?​www.zhihu.com
74d6193224c2da2322052568570f9a56.png

代码如下

7ef12dd851152734af3056b1ef86d379.png

b884f950b5fd4cd1b1c3fa24bddb7f2e.png

做完这些就实现了一个可响应点击的雷达图了。

dce6be129316de829f307a37e6233c3f.gif

描边

一开始觉得这就不算个问题,搞两个权重一样但是半径不一样的雷达图不就能实现了嘛。试了试发现,问题没有这么简单。

a5ae1bbc74a6e199f4022f3ee2e05617.png

因为权重不均匀,所以会导致描边也不均匀,为了实现均匀的描边,还需要额外的工作。

解决办法是额外进行边的绘制。对于多边形的每一个顶点 C ,我们按逆时针方向找出它的上一个 A 与下一个顶点 B ,并且得到它相邻的两条边的向外的垂线,把 A 与 B 沿着垂线向外延伸得到 E 与 F,把 E 与 F 沿着边的方向延伸,相交于点 P,对每个顶点重复上述步骤,就能得到外框的所有点了。

4c276afd6549ed718744a06462e7c889.png

顶点构造代码

990eceb2303eb84e1153b244b0924205.png

下标数组构造

13bee31097f4cef5945a9f182569efdc.png

获得交点

38bd20b8e5617bc862338e5e3d3bebeb.png

获得垂线

aa9348855ea616339b7949593b705950.png

最后看效果

4c0509a596fa65bf6c2c35db368a91e7.png

总结

网上 Unity 实现 雷达图的代码能找到不少,但是我发现基本都止步于网格的构造,并没有将点击响应的计算以及均匀描边的实现,有的更过分,甚至连 uv 都不肯算,没办法只能自己撸一个,把一些中学几何的东西又捡起来过了一遍,总的来说,这个过程还是有所收获的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值