1. 程式人生 > >Unity 屬性雷達圖效果

Unity 屬性雷達圖效果

最終效果圖:


遊戲中難免會展示英雄的各個屬性值,雷達圖是比較簡潔直觀並且符合使用者習慣的展示方式之一。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;
    }
}
百度網盤地址:連結:http://pan.baidu.com/s/1c2yx2ec 密碼:ml45