游戏中难免会展示英雄的各个属性值,雷达图是比较简洁直观并且符合用户习惯的展示方式之一。3D中生成的任何面都是由一个个三角形组成的,要实现图中的效果我们需要在程序中动态生成正五边形面片,我们需要六个顶点(包含中心点)。设中心点O为(0,0),经过x轴的顶点A为(45,0),那么如何根据确定这五个顶点呢?正五边形的顶点必定都在一个圆上,已知半径为R,其余的顶点都是OA向量经过旋转得到,四不四很简单。
向量旋转公式:
x' = xcos(theta) - ysin(theta);
y' = xsin(theta) + ycos(theta);
这里我为大家做好了一个示例:
1.将radar预置拖到场景里
2.设置顶点数组长度为6(生成五边形),运行看效果,输入任意正整数n,会生成n-1边形
3.修改其中一个顶点的Z(0~1)值,这时能观察到生成的五边形发生变化
4.跟底图搭配就能达到完美效果了。
雷达脚本Radar.cs
using UnityEngine;
using System.Collections;
public class Radar : MonoBehaviour
{
//网格模型顶点数量
private int VERTICES_COUNT;
[Tooltip("边数为数组长度减1")]
//顶点数组
public Vector3[] vertices;
//三角形数组
int[] triangles;
public float scale;
MeshFilter meshFilter;
Mesh mesh;
float pi = 3.1415f;
void Start()
{
CreateMesh();
SetVertices();
}
void OnGUI()
{
if (meshFilter == null)
{
CreateMesh();
SetVertices();
}
Apply();
if (GUILayout.Button("Apply "))
{
Apply();
}
}
void CreateMesh()
{
meshFilter = (MeshFilter)GameObject.Find("radar").GetComponent(typeof(MeshFilter));
mesh = meshFilter.mesh;
}
void SetVertices()
{
VERTICES_COUNT = vertices.Length;
int triangles_count = VERTICES_COUNT - 1;
triangles = new int[triangles_count * 3];
//设定原点坐标
vertices[0] = new Vector3(0, 0, 1);
//首个在x轴上的坐标点
vertices[1] = new Vector3(45, 0, 1);
//每个三角形角度
float everyAngle = 360 / triangles_count;
for (int i = 2; i < vertices.Length; i++)
{
var angle = GetRadians(everyAngle * (i - 1));
vertices[i] = new Vector3(45 * Mathf.Cos(angle), 45 * Mathf.Sin(angle), 1);
}
int idx = 0;
int value = 0;
for (int i = 0; i < triangles.Length; i++)
{
if (i % 3 == 0)
{
triangles[i] = 0;
value = idx;
idx++;
}
else
{
value++;
if (value == VERTICES_COUNT)
value = 1;
Debug.Log("value " + value);
triangles[i] = value;
}
}
//vertices[0] = new Vector3(0, 0, 1);
//vertices[1] = new Vector3(45, 0, 1);
//vertices[2] = new Vector3(45 * Mathf.Cos(GetRadians(75)), 45 * Mathf.Sin(GetRadians(75)), 1);
//vertices[3] = new Vector3(-45 * Mathf.Cos(GetRadians(36)), 45 * Mathf.Sin(GetRadians(36)), 1);
//vertices[4] = new Vector3(-45 * Mathf.Cos(GetRadians(36)), -45 * Mathf.Sin(GetRadians(36)), 1);
//vertices[5] = new Vector3(45 * Mathf.Cos(GetRadians(75)), -45 * Mathf.Sin(GetRadians(75)), 1);
//每三个顶点为一个三角面
//triangles[0] = 0;
//triangles[1] = 1;
//triangles[2] = 2;
//triangles[3] = 0;
//triangles[4] = 2;
//triangles[5] = 3;
//triangles[6] = 0;
//triangles[7] = 3;
//triangles[8] = 4;
//triangles[9] = 0;
//triangles[10] = 4;
//triangles[11] = 5;
//triangles[12] = 0;
//triangles[13] = 5;
//triangles[14] = 1;
}
float GetRadians(float angle)
{
return pi / 180 * angle;
}
void Apply()
{
Vector3[] tmps = new Vector3[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
tmps[i] = vertices[i] * vertices[i].z * scale;
}
mesh.vertices = tmps;
mesh.triangles = triangles;
}
}