欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用UGUI的Image画面积图

程序员文章站 2022-03-11 10:28:34
...

使用UGUI的Image画面积图


哈哈,本大猫又回来了,新的工作,新的生活。愿自己和看到这段话的你们,生活越来越辛福美满!


唔,先上图:
用UGUI的Image画面积图


1. 参考引用:

[1] https://www.cnblogs.com/jeason1997/p/5130413.html 在Unity中使用UGUI修改Mesh绘制几何图形 (作者:Jeason1997)


2. 实现思路:
UGUI的Image实现方式和一般的Mesh一样,都是通过顶点描绘出来的。通过察看Image这个类的代码,发现它提供了虚函数,需要用到的关键函数是OnPopulateMesh(VertexHelper toFill)。


3. 好像也没啥需要多说的,就是给出顶点(位置,颜色,VU),然后一个一个三角形按照顺时针方向连起来。emmmm,上代码~


1)核心代码:

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

public class DrawAreaDiagram : Image {
    private List<float> percentArray = new List<float>();//百分比数组
    private float brokenLineWidth = 3f;//折线的宽度
    private Vector3 origin;//绘图区域的原点
    private Vector2 area;//宽高范围
    private Color[] lineColors;//折线
    private Color[] imageTopColors;//顶部
    private Color[] imageButtomColors;//底部
    private Vector3[] vertPositions;
    private int times = 3;

    private float pointQuadlength = 6f;//节点的边长
    private Vector3[] pointQuadPositions;//节点的位置
    private int quadSides = 4;//节点的边数

    private void Update()
    {
        SetVerticesDirty();//刷新
    }

    protected override void OnPopulateMesh(VertexHelper toFill)
    {
        if (percentArray.Count == 0)
        {
            base.OnPopulateMesh(toFill);
        }
        else
        {
            toFill.Clear();
            for (int i = 0; i < percentArray.Count; i++)
            {
                toFill.AddVert(vertPositions[i * times], imageButtomColors[i], new Vector2((float)i / percentArray.Count, 0));//下
                toFill.AddVert(vertPositions[i * times + 1], imageTopColors[i], new Vector2((float)i / percentArray.Count, 0.25f));//上
                toFill.AddVert(vertPositions[i * times + 1], lineColors[i], new Vector2((float)i / percentArray.Count, 0.25f));//上
                toFill.AddVert(vertPositions[i * times + 2], lineColors[i], new Vector2((float)i / percentArray.Count, 0.5f));//顶
            }

            for (int i = 0; i < percentArray.Count; i++)
            {
                toFill.AddVert(pointQuadPositions[i * quadSides], lineColors[i], new Vector2((float)i / percentArray.Count, 0.5f));//下
                toFill.AddVert(pointQuadPositions[i * quadSides + 1], lineColors[i], new Vector2((float)i / percentArray.Count, 1f));//上
                toFill.AddVert(pointQuadPositions[i * quadSides + 2], lineColors[i], new Vector2((float)i / percentArray.Count, 0.5f));//上
                toFill.AddVert(pointQuadPositions[i * quadSides + 3], lineColors[i], new Vector2((float)i / percentArray.Count, 1f));//顶
            }

            for (int i = 0; i < percentArray.Count - 1; i++)
            {
                toFill.AddTriangle(i * 4 + 0, i * 4 + 1, i * 4 + 4);
                toFill.AddTriangle(i * 4 + 1, i * 4 + 5, i * 4 + 4);

                toFill.AddTriangle(i * 4 + 2, i * 4 + 3, i * 4 + 6);
                toFill.AddTriangle(i * 4 + 3, i * 4 + 7, i * 4 + 6);
            }

            for (int i = percentArray.Count; i < percentArray.Count * 2; i++)
            {
                toFill.AddTriangle(i * 4 + 0, i * 4 + 1, i * 4 + 2);
                toFill.AddTriangle(i * 4 + 1, i * 4 + 3, i * 4 + 2);
            }
        }
    }

    public void InitDrawingParam(float _pointQuadlength,float buttomAlpha,float topAplha, float lineWidth,Color[] colors,List<float> _percentArray)
    {
        if (colors.Length != _percentArray.Count)
        {
            Debug.LogError("ArrayList is Wrong!");
            return;
        }
        pointQuadlength = _pointQuadlength;
        percentArray = _percentArray;//百分比数组
        brokenLineWidth = lineWidth;//折线的宽

        GetDrawArea();//得到绘图区域
        CreateVertPositions(_percentArray);//获取到每个顶点的坐标

        lineColors = new Color[colors.Length];
        imageTopColors = new Color[colors.Length];
        imageButtomColors = new Color[colors.Length];
        //颜色
        for (int i = 0; i < colors.Length; i++)
        {
            lineColors[i] = colors[i];
            imageTopColors[i] = colors[i];
            imageButtomColors[i] = colors[i];
            //透明度
            lineColors[i].a = 1;
            imageTopColors[i].a = _percentArray[i] * topAplha;
            imageButtomColors[i].a = buttomAlpha;
        }   
    }
    private void CreateVertPositions(List<float> _percentArray)
    {
        vertPositions = new Vector3[_percentArray.Count * times];//折线顶,折线底,图片底
        pointQuadPositions = new Vector3[_percentArray.Count * quadSides];//节点
        int arrayCount = _percentArray.Count - 1;
        for (int i = 0; i < arrayCount + 1; i++)
        {
            vertPositions[times * i] = origin + new Vector3(area.x * i / arrayCount, 0, 0);//图片底
            vertPositions[times * i + 1] = vertPositions[times * i] + new Vector3(0, area.y * _percentArray[i] - brokenLineWidth / 2);//折线底
            vertPositions[times * i + 2] = vertPositions[times * i + 1] + new Vector3(0, brokenLineWidth);//折线顶

            pointQuadPositions[quadSides * i] = origin + new Vector3(area.x * i / arrayCount - pointQuadlength / 2, area.y * _percentArray[i] - pointQuadlength / 2);//节点左下
            pointQuadPositions[quadSides * i + 1] = origin + new Vector3(area.x * i / arrayCount - pointQuadlength / 2, area.y * _percentArray[i] + pointQuadlength / 2);//节点左上
            pointQuadPositions[quadSides * i + 2] = origin + new Vector3(area.x * i / arrayCount + pointQuadlength / 2, area.y * _percentArray[i] - pointQuadlength / 2);//节点右下
            pointQuadPositions[quadSides * i + 3] = origin + new Vector3(area.x * i / arrayCount + pointQuadlength / 2, area.y * _percentArray[i] + pointQuadlength / 2);//节点右上
        } 
    }
    //原点,宽,高
    private void GetDrawArea()
    {
        area = rectTransform.rect.size;
        origin = -(Vector3)area / 2;
    }
} 

2)测试代码:

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

public class DrawTest : MonoBehaviour {
    private DrawAreaDiagram areaDiagram;
    # region 测试代码
    protected void Start()
    {
        areaDiagram = GetComponentInChildren<DrawAreaDiagram>(true);
        StartCoroutine(FreshImage());
    }

    IEnumerator FreshImage()
    {
        while (true)
        {
            yield return new WaitForSeconds(0.9f);
            Test();
        }
    }
    protected void Test()
    {
        Color[] colors = new Color[19];
        List<float> _percentArray = new List<float>();
        for (int i = 0; i < colors.Length; i++)
        {
            colors[i] = new Color(Random.Range(0.1f, 1f), Random.Range(0.1f, 1f), Random.Range(0.1f, 1f), 1);
            _percentArray.Add(Random.Range(0.1f, 1f));
        }
        areaDiagram.InitDrawingParam(29f, 0f, 0.9f, 5f, colors, _percentArray);
    }
    #endregion

}

4. 使用大概是这样子的:(父节点挂测试代码)
用UGUI的Image画面积图

相关标签: Image AreaDiagram