文章目录

  • 一、前言
  • 二、最终效果
  • 三、原理
  • 四、具体实现
    • 1、雷达图背景图
    • 2、封装UIPolygon.cs
    • 3、制作预设
    • 4、测试脚本RadarTest.cs
  • 五、运行测试
  • 六、结束语
  • 七、附录:UIPolygon.cs完整代码

一、前言

点关注不迷路,持续输出Unity干货文章。

嗨,大家好,我是新发。
不知道大家有没有看过这部动画片《因为太怕痛就全点了防御力》:


女主在好友理沙的引诱之下,开始玩起最新的VRMMO 《NewWorldOnline》,因为太怕痛,所以全点了防御力。
剧情挺有意思的,大家感兴趣的话可以去看下这部动画片。
言归正传,今天我要讲的,就是如何使用Unity UGUI制作雷达图(或者天赋图/属性图/能力图)。

二、最终效果


本文Demo工程已上传到CodeChina,感兴趣的同学可自行下载学习。
地址:https://codechina.csdn.net/linxinfa/UnityUGUIPolygonRadarGraphicDemo
注:我使用的Unity版本:2020.2.7f1c1 (64-bit)

三、原理

UGUI中,不管是RawImageImage还是Text,它们都是继承MaskableGraphic的,而MaskableGraphic又是继承Graphic的,在Graphic中有个OnPopulateMesh方法。

protected virtual void OnPopulateMesh(VertexHelper vh);

参数是VertexHelper,我们可以通过VertexHelper添加顶点,从而实现多边形的绘制。
画成图就是这样子:

四、具体实现

1、雷达图背景图

首先,我们先制作雷达背景图,如下:

导入Unity工程中:

2、封装UIPolygon.cs

封装UIPolygon.cs脚本,它继承MaskableGraphic,重写它的OnPopulateMesh方法。
完整代码见文章末尾。

3、制作预设

制作一个雷达图预设,如下:

Hierarchy层级视图如下:

其中UIPolygon节点挂CanvasRenderer组件和UIPolygon组件,

其中UIPolygon组件相关的参数设置如下:

4、测试脚本RadarTest.cs

写一个测试脚本RadarTest.cs,挂在Canvas节点上,并赋值成员变量:

RadarTest.cs代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 测试雷达图
/// </summary>
public class RadarTest : MonoBehaviour
{public UIPolygon uiPolygon;List<float> datas = new List<float>();void Start(){// 防御力datas.Add(0.92f);// 智力datas.Add(0.31f);// 灵巧datas.Add(0.36f);// 力量datas.Add(0.28f);// 敏捷datas.Add(0.35f);uiPolygon.DrawPolygon(datas);}private void Update(){if(Input.GetMouseButtonDown(0)){for(int i=0,cnt = datas.Count;i<cnt;++i){datas[i] = Random.Range(0f, 1f);}// 重新随机雷达数据uiPolygon.DrawPolygon(datas);}}}

五、运行测试

运行Unity,测试效果如下:

我们可以在Inspector面板看到我们通过代码设置的顶点数据生效了(注意第5个顶点是与第0个顶点重合的):

我们可以手动拖拉这些顶点,效果如下:

六、结束语

完毕。
喜欢Unity的同学,不要忘记点击关注,如果有什么Unity相关的技术难题,也欢迎留言或私信~

七、附录:UIPolygon.cs完整代码

UIPolygon.cs代码如下:

using UnityEngine.UI;
using UnityEngine;
using System.Collections.Generic;/// <summary>
/// UI多边形
/// </summary>
public class UIPolygon : MaskableGraphic
{[SerializeField]Texture m_Texture;/// <summary>/// 填充/// </summary>public bool fill = true;/// <summary>/// 边数/// </summary>[Range(3, 360)]public int sides = 3;/// <summary>/// 旋转角度/// </summary>[Range(0, 360)]public float rotation = 0;/// <summary>/// 顶点数组/// </summary>[Range(0, 1)]public float[] VerticesDistances = new float[3];private float size = 0;public override Texture mainTexture{get{return m_Texture == null ? s_WhiteTexture : m_Texture;}}public Texture texture{get{return m_Texture;}set{if (m_Texture == value) return;m_Texture = value;SetVerticesDirty();SetMaterialDirty();}}#region 提供外部的接口public void DrawPolygon(int _sides){sides = _sides;VerticesDistances = new float[_sides + 1];for (int i = 0; i < _sides; i++) VerticesDistances[i] = 1;}public void DrawPolygon(List<float> datas){List<float> finalDatas = new List<float>(datas);sides = finalDatas.Count;// 加上最后一个点,最后一个点与第一个点重合finalDatas.Add(finalDatas[0]);VerticesDistances = finalDatas.ToArray();// 触发重绘SetVerticesDirty();}#endregionvoid Update(){// 根据宽高适配尺寸size = rectTransform.rect.width;if (rectTransform.rect.width > rectTransform.rect.height)size = rectTransform.rect.height;elsesize = rectTransform.rect.width;}protected UIVertex[] SetVertexs(Vector2[] vertices, Vector2[] uvs){UIVertex[] vbo = new UIVertex[4];for (int i = 0; i < vertices.Length; i++){var vert = UIVertex.simpleVert;vert.color = color;vert.position = vertices[i];vert.uv0 = uvs[i];vbo[i] = vert;}return vbo;}/// <summary>/// 重写OnPopulateMesh方法/// </summary>/// <param name="vh"></param>protected override void OnPopulateMesh(VertexHelper vh){vh.Clear();Vector2 prevX = Vector2.zero;Vector2 prevY = Vector2.zero;Vector2 uv0 = new Vector2(0, 0);Vector2 uv1 = new Vector2(0, 1);Vector2 uv2 = new Vector2(1, 1);Vector2 uv3 = new Vector2(1, 0);Vector2 pos0;Vector2 pos1;Vector2 pos2;Vector2 pos3;float degrees = 360f / sides;int vertices = sides + 1;if (VerticesDistances.Length != vertices){VerticesDistances = new float[vertices];for (int i = 0; i < vertices - 1; i++) VerticesDistances[i] = 1;}// 最后一个顶点,也即是第一个顶点VerticesDistances[vertices - 1] = VerticesDistances[0];for (int i = 0; i < vertices; i++){float outer = -rectTransform.pivot.x * size * VerticesDistances[i];float inner = -rectTransform.pivot.x * size * VerticesDistances[i];float rad = Mathf.Deg2Rad * (i * degrees + rotation);float c = Mathf.Cos(rad);float s = Mathf.Sin(rad);uv0 = new Vector2(0, 1);uv1 = new Vector2(1, 1);uv2 = new Vector2(1, 0);uv3 = new Vector2(0, 0);pos0 = prevX;pos1 = new Vector2(outer * c, outer * s);if (fill){pos2 = Vector2.zero;pos3 = Vector2.zero;}else{pos2 = new Vector2(inner * c, inner * s);pos3 = prevY;}prevX = pos1;prevY = pos2;vh.AddUIVertexQuad(SetVertexs(new[] { pos0, pos1, pos2, pos3 }, new[] { uv0, uv1, uv2, uv3 }));}}
}

【游戏开发实战】Unity UGUI制作雷达图/天赋图/属性图/能力图,因为太怕痛就全点了防御力相关推荐

  1. 【游戏开发实战】Unity手游第一人称视角,双摇杆控制,FPS射击游戏Demo(教程 | 含Demo工程源码)

    文章目录 一.前言 二.实现方案 1.无主之地,第一人称视角 2.我之前做的摇杆控制 3.第一人称视角 + 摇杆控制 三.开始实战 1.资源获取:Unity AssetStore 2.Low Poly ...

  2. 【游戏开发实战】用Go语言写一个服务器,实现与Unity客户端通信(Golang | Unity | Socket | 通信 | 教程 | 附工程源码)

    文章目录 一.前言 二.Go开发环境搭建(Windows系统) 1.安装Go命令行工具 2.创建GoWorkspace目录 3.配置GOPATH环境变量 4.配置GOPROXY代理 5.安装VSCod ...

  3. 【游戏开发实战】Unity从零开发多人视频聊天功能,无聊了就和自己视频聊天(附源码 | Mirror | 多人视频 | 详细教程)

    文章目录 一.前言 二.思考问题与解决方案 1.思考问题 2.解决方案 2.1.Unity中如何开启摄像头并对图像进行采样 2.2.图像如何中转给其他客户端 2.3.如何实现清晰度切换 2.4.客户端 ...

  4. 微信小游戏开发实战教程15-关卡编辑器的制作以及关卡分享功能的实现

    微信小游戏开发实战系列的第15篇. 本节主要内容有游戏中的关卡编辑器的实现思路以及如何利用分享功能将自己制作的关卡与好友分享. 如果你没有任何的游戏开发经验,欢迎阅读我的"人人都能做游戏&q ...

  5. 【游戏开发实战】教你在Unity中实现模型消融化为灰烬飘散的效果(ShaderGraph | 消融 | 粒子系统 | 特效)

    文章目录 一.前言 二.ShaderGraph环境准备 三.模型准备:原神角色模型 四.实现思路 1.效果一的实现思路 2.效果二的实现思路 五.ShaderGraph具体实现 1.效果一 1.1.创 ...

  6. ​Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机

    ​Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机 Unity中制作一个望远镜 本节制作的望远镜,在鼠标左键按下时,看到的视图会变大:当不再按下的时候,会慢慢缩小成原来的视图.游戏中时常出现 ...

  7. 《Unity 5.x游戏开发实战》一1.9 添加一个水平面

    本节书摘来异步社区<Unity 5.x游戏开发实战>一书中的第1章,第1.9节,作者: Alan Thorn 译者: 李华峰 责编: 胡俊英,更多章节内容可以访问云栖社区"异步社 ...

  8. 《Unity 2D与3D手机游戏开发实战》简介

    #好书推荐##好书奇遇季#<Unity 2D与3D手机游戏开发实战>,京东当当天猫都有发售.彩色印制,定价89元,网店打折销售更便宜.本书配套源码.PPT课件,适合Unity游戏开发初学者 ...

  9. 【Unity】动作游戏开发实战详细分析-25-角色残影效果的实现

    [Unity]动作游戏开发实战详细分析-25-角色残影效果的实现 基本思路 Unity中的蒙皮网格组件提供了一个接口BakeMesh,允许我们拿到当前动画帧的网格数据,借此可对烘焙网格使用半透明的边缘 ...

最新文章

  1. The application does not contain a valid bundle identifier.解决方法
  2. Win32 结构化异常处理(SEH)探秘【下篇】
  3. Android混淆详解
  4. Android空间架构与自定义控件详解-更新中
  5. 12.PDE与PTE
  6. 聚类dbi指数_人脸聚类常用评价指标
  7. gentoo rt-thread scons --menuconfig libs/lxdialog/util.o: undefined reference to symbol 'nodelay'
  8. php webservice 上传,PHP实现WebService服务
  9. 1.2开发文档简读,了解全貌.mp4
  10. gridview不换行,高亮显示
  11. 关于findViewById返回空指针的错误
  12. win10磁盘管理界面各系统分区介绍
  13. win10 预览版启用 Hyper-V 虚拟机 装 boot2docker找不到菜单按钮问题
  14. 阿里出品的最新版 Java 开发手册,嵩山版,扫地僧
  15. OpenCV-像素值读写(java版)
  16. 2022年中式烹调师(初级)考试题库及在线模拟考试
  17. “盲人”马云:骑着盲虎贩卖梦想
  18. Keras CIFAR-10彩色图像物体识别 卷积神经网络
  19. 各类炫酷二维码的制作(附带GUI工具开发)
  20. 基于ssm+maven+idea的滴滴网络租车系统设计与实现

热门文章

  1. 计算机组成am2901,计算机组成原理实验1
  2. 步进电机-STM32单片机控制四相五线步进电机的程序
  3. Pytorch优化器全总结(四)常用优化器性能对比 含代码
  4. Lesson7:HTTP协议
  5. 应届生如何写简历得到企业关注
  6. 读AlphaZero论文随想
  7. windows 10 Quick Assist 远程协助工具
  8. Spring AOP中@Pointcut切入点表达式详解
  9. 盘点2020 | Cocos 精选 2D、3D 游戏合集
  10. bootstrap实现轮播图 --设置图片大小等于父容器大小