Blink

纸上得来终觉浅,绝知此事要躬行

Unity中实现雷达属性图

最终效果

《Unity中实现雷达属性图》

组件脚本代码

/*******************************************************************
 * 文件名: Radar.cs
 * 时  间: 2020-12-15
 * 作  者: Blink
 * 描  述: 雷达图组件
 *******************************************************************/

namespace UnityEngine.UI
{
    [AddComponentMenu("UI/Radar", 40)]
    public class Radar : MaskableGraphic
    {
        public float radius = 200f;
        [SerializeField]
        [Range(0f, 1f)]
        private float[] values = new float[5];

        /// <summary>
        /// 设置边数
        /// </summary>
        /// <param name="count">默认为5边形,最小边数为3</param>
        public void SetEdges(int count = 5)
        {
            values = new float[count];
            SetVerticesDirty();
        }

        /// <summary>
        /// 更新值
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="value">新值(范围: [0f,1f] )</param>
        public void UpdateValue(int index, float value)
        {
            if (CheckIndexValidity(index))
            {
                value = Mathf.Clamp(value, 0f, 1f);
                values[index] = value;
                SetVerticesDirty();
            }
        }

        /// <summary>
        /// 获取值
        /// </summary>
        /// <param name="index">索引</param>
        /// <returns>如果没有获取到则返回-1</returns>
        public float GetValue(int index)
        {
            if (CheckIndexValidity(index))
            {
                return values[index];
            }
            return -1f;
        }

        /// <summary>
        /// 索引安全检查
        /// </summary>
        /// <param name="index"></param>
        /// <returns>是否安全</returns>
        private bool CheckIndexValidity(int index)
        {
            if (index >= values.Length)
                throw new System.IndexOutOfRangeException();
            else
                return true;
        }

        protected override void OnPopulateMesh(VertexHelper toFill)
        {
            toFill.Clear();
            float radian = 2 * Mathf.PI / values.Length;
            toFill.AddVert(new Vector3(0, 0, 0), color, Vector2.zero);
            for (int i = 0; i < values.Length; i++)
            {
                float y = radius * values[i] * Mathf.Cos(radian * i);
                float x = radius * values[i] * Mathf.Sin(radian * i);
                toFill.AddVert(new Vector3(x, y, 0), color, Vector2.zero);
                if (i < values.Length - 1)
                {
                    toFill.AddTriangle(i + 1, 0, i + 2);
                }
                else
                {
                    toFill.AddTriangle(i + 1, 0, 1);
                }
            }
        }
    }
}

编辑器脚本代码

/*******************************************************************
 * 文件名: RadarEditor.cs
 * 时  间: 2020-12-15
 * 作  者: Blink
 * 描  述: 用于编辑器中编辑雷达图组件
 *******************************************************************/

using UnityEngine.UI;

namespace UnityEditor.UI
{
    [CustomEditor(typeof(Radar), true)]
    public class RadarEditor : GraphicEditor
    {
        SerializedProperty m_Radius;
        SerializedProperty m_Values;

        protected override void OnEnable()
        {
            base.OnEnable();
            m_Radius = serializedObject.FindProperty("radius");
            m_Values = serializedObject.FindProperty("values");
        }

        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            //serializedObject.Update();
            EditorGUILayout.PropertyField(m_Radius);
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(m_Values);
            if (EditorGUI.EndChangeCheck())
            {
                if (m_Values.arraySize <= 3)
                {
                    m_Values.arraySize = 3;
                }
            }
            serializedObject.ApplyModifiedProperties();
        }
    }
}

使用

  1. 创建一个空物体,挂载Radar脚本
  2. Radius为雷达图的半径
  3. 在Values中可以调整各个顶点的值

《Unity中实现雷达属性图》

点赞

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注