UGUI 绘制自定义折线图

使用

这里写图片描述

  1. 挂载LineChart.cs
  2. 点击autoCreate按钮,会创建子节点,可以在子节点上挂载自定义控件

实现

LineChart.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace ViVi.UIExtensions
{
    [ExecuteInEditMode]
    [RequireComponent(typeof(PTLineChartRender))]


    public class LineChart : MonoBehaviour
    {
        public GameObject[] childNode;




        void Awake()
        {
        }

        // Update is called once per frame
        void Update()
        {
            GameObject go;
            Vector2 size = GetComponent<RectTransform>().rect.size;
            LineChartRender render = GetComponent<LineChartRender>();
            for (int i = 0; i < childNode.Length; i++)
            {
                go = childNode[i];
                if(go!=null)
                {
                    go.GetComponent<RectTransform>().anchoredPosition = new Vector2((size.x / (render.values.Length-1)) * i - size.x*0.5f ,size.y * render.values[i]- size.y*0.5f);
                }
            }
        }
    }
}

LineChartRender.cs

using UnityEngine;
using UnityEngine.UI; 

namespace ViVi.UIExtensions{
    public class LineChartRender : MaskableGraphic {

        [Range (0f, 1f)] 
        public float[] values = new float[2]{1,1};


        public Color BottomColor = Color.white;

        public Color TopColor = Color.white;


        public bool useEdge = false;


        public bool useLine = false;

        [Range (0f, 2.5f)] 
        public float lineWidth = 1.0f;
        [Range (0f, 2.5f)] 
        public float edgeWidth = 1.0f;

        public Color lineColor = Color.black;

        public Color edgeColor = Color.black;



        protected override void OnPopulateMesh(VertexHelper vh)
        {
            Vector2 size = GetComponent<RectTransform>().rect.size;
            vh.Clear();
            int partCount = values.Length;
            float spx = size.x / (float) (partCount - 1);
            float nx = 0;
            float nx1 = 0;


            float height = size.y;

            float sph = size.y * 0.5f;
            float spw = size.x * 0.5f;
            for (int i = 0; i < partCount - 1; i++)
            {
                nx = spx * i - spw;
                nx1 = nx + spx;

                float x1=  (float)i/(float)partCount;
                float x2=  (float)(i+1)/(float)partCount;

                //UIVertex[] vertexs = new UIVertex[4];
                UIVertex v1 = UIVertex.simpleVert;
                UIVertex v2 = UIVertex.simpleVert;
                UIVertex v3 = UIVertex.simpleVert;
                UIVertex v4 = UIVertex.simpleVert;

                v1.position = new Vector2(nx, height * values[i]  - sph);
                v2.position = new Vector2(nx, -sph);
                v3.position = new Vector2(nx1, -sph);
                v4.position = new Vector2(nx1, height * values[i + 1] - sph);


                v1.color = Color.Lerp(BottomColor, TopColor, values[i]);
                v2.color = Color.Lerp(BottomColor, TopColor, 0);
                v3.color = Color.Lerp(BottomColor, TopColor, 0);
                v4.color = Color.Lerp(BottomColor, TopColor, values[i+ 1]);



                v1.uv0 = new Vector2(x1,values[i]);
                v2.uv0 = new Vector2(x1,0);
                v3.uv0 = new Vector2(x2,0);
                v4.uv0 = new Vector2(x2,values[i+ 1]);

                if (useLine)
                {
                    if(i==0)
                        vh.AddUIVertexQuad (GetLine (v1.position, v2.position,lineColor,lineWidth));
                    vh.AddUIVertexQuad (GetLine (v3.position, v4.position,lineColor,lineWidth));
                }


                vh.AddUIVertexQuad(new UIVertex[4]{v4,v3,v2,v1});




                if (useEdge)
                {
                    vh.AddUIVertexQuad (GetLine (v1.position, v4.position,edgeColor,edgeWidth));
                }


            }

        }



        private UIVertex[] GetLine (Vector2 start, Vector2 end ,Color lcolor ,float lwidth) {
            UIVertex[] vs = new UIVertex[4];
            Vector2[] uv = new Vector2[4];
            uv[0] = new Vector2(0, 0);
            uv[1] = new Vector2(0, 1);
            uv[2] = new Vector2(1, 0);
            uv[3] = new Vector2(1, 1);
            Vector2 v1 = end - start;
            Vector2 v2 = (v1.y == 0f) ? new Vector2 (0f, 1f) : new Vector2 (1f, -v1.x / v1.y);
            v2.Normalize ();
            v2 *= lwidth / 2f;
            Vector2[] pos = new Vector2[4];
            pos[0] = start + v2;
            pos[1] = end + v2;
            pos[2] = end - v2;
            pos[3] = start - v2;
            for (int i = 0; i < 4; i++) {
                UIVertex v = UIVertex.simpleVert;
                v.color = lcolor;
                v.position = pos[i];
                v.uv0 = uv[i];
                vs[i] = v;
            }
            return vs;
        }


    }
}

Editor 编辑器扩展

LineChartEditor.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;


namespace ViVi.UIExtensions
{
    [CustomEditor(typeof(LineChart))]
    [CanEditMultipleObjects]
    public class LineChartEditor: Editor
    {

        SerializedProperty childNode;

        private LineChart lineChart;
        void OnEnable()
        {
            lineChart = (LineChart) target;
            childNode = serializedObject.FindProperty("childNode");


        }

        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            DrawDefaultInspector();

            if (GUILayout.Button("Auto Create"))
            {       
                LineChartRender render = null;
                render = lineChart.gameObject.GetComponent<LineChartRender>();
                childNode.ClearArray();
                childNode.arraySize = 0;
                GameObject go;
                Vector2 size = lineChart.GetComponent<RectTransform>().rect.size;
                for (int i = 0; i < render.values.Length; i++)
                {
                    Transform tf = lineChart.transform.FindChild("v" + i);
                    RectTransform rect;
                    if (tf == null)
                    {
                        go = new GameObject();
                        rect = go.AddComponent<RectTransform>();
                        go.name = "v" + i;
                        //go.transform.parent = lineChart.transform;
                        rect.SetParent(lineChart.transform,false);

                    }
                    else
                    {
                        go = tf.gameObject;
                        rect = tf.GetComponent<RectTransform>();
                    }

                    rect.localScale = Vector3.one;
                    rect.localRotation = Quaternion.identity;
                    rect.pivot = new Vector2(0.5f,0.5f);
                    rect.sizeDelta = new Vector2(10,10);

                    rect.anchoredPosition = new Vector2((size.x / (render.values.Length-1)) * i - size.x*0.5f ,size.y * render.values[i]- size.y*0.5f);

                    childNode.arraySize += 1;
                    SerializedProperty npc =childNode.GetArrayElementAtIndex(childNode.arraySize-1);
                    npc.objectReferenceValue = go;
                    serializedObject.ApplyModifiedProperties();
                }
            }


            if (GUILayout.Button("Clean Child"))
            {
                childNode.ClearArray();
                childNode.arraySize = 0;
                List<GameObject> child = new List<GameObject>(); 
                for (int i = 0; i < lineChart.transform.childCount; i++)
                {
                    child.Add(lineChart.transform.GetChild(i).gameObject);
                }
                for (int i = 0; i < child.Count; i++)
                {
                    GameObject.DestroyImmediate(child[i]);
                }
                child.Clear();
                serializedObject.ApplyModifiedProperties();
            }
        }
    }
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值