UGUI 绘制自定义折线图

来源:互联网 发布:php web 文件上传 编辑:程序博客网 时间:2024/05/22 12:10

使用

这里写图片描述

  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();            }        }    }}
原创粉丝点击