UI绘制

                   Unity中的UGUI对外还是很开放的,查看了MaskableGraphic类,发现UI的绘制都是继承自此类,然后在OnPopulateMesh方法中进行UI的绘制,要做自己的UI需要继承此类,然后重写OnPopulateMesh方法(这个方法有两个重载);这里就重写OnPopulateMesh(VertexHelper vh),运用VertexHelper 对象的AddUIVertexQuad方法绘制UI;


主要看下面的方法:

  private UIVertex[] GetQuad(Vector2 startPos, Vector2 endPos, Color color0, float lineWidth = 2)
    {
        var dis = Vector2.Distance(startPos, endPos);
        float x = lineWidth * 0.5f * (endPos.y - startPos.y) / dis;
        float y = lineWidth * 0.5f * (endPos.x - startPos.x) / dis;
        if (x <= 0) x = -x;
        else y = -y;

        UIVertex[] vertexs = new UIVertex[4];
        vertexs[0].position = new Vector2(startPos.x + x, startPos.y + y);
        vertexs[1].position = new Vector2(endPos.x + x, endPos.y + y);
        vertexs[2].position = new Vector2(endPos.x - x, endPos.y - y);
        vertexs[3].position = new Vector2(startPos.x - x, startPos.y - y);

        for (int i = 0; i < vertexs.Length; i++)
        {
            vertexs[i].color = color0;
        }
        return vertexs;
    }
    private UIVertex[] GetQuad(Vector2 first, Vector2 second, Vector2 third, Vector2 four, Color color0)
    {
        UIVertex[] vertexs = new UIVertex[]
        {
            new UIVertex { position=first,color=color0,uv0=Vector2.zero},
            new UIVertex { position=second,color=color0,uv0=Vector2.zero},
            new UIVertex { position=third,color=color0,uv0=Vector2.zero},
            new UIVertex { position=four,color=color0,uv0=Vector2.zero}
        };
        return vertexs;

    }


直接上完整代码看案例:

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

public enum LineType
{
    None,
    FullLine,
    LinaryLine
}
[Serializable]
public class FunctionBase
{
    [Range(40, 100)]
    public float axisScale = 50;
    [Range(3, 20)]
    public float arrowScale = 4;
    public LineType lineType = LineType.FullLine;
    public bool isShowScale = false;
    public float scaleLength = 3;
    [Range(1,100)]
    public float scaleValue = 50;
    public float lineLength = 3;
    [Range(3, 8)]
    public float spaceLength = 3;
    [Range(1.5f, 10)]
    public float lineWidth = 1.5f;
}
public class FunctionalFormula
{
    public  Func<float, float> formula;
    public Color color;
    public float LineWidth;
    public FunctionalFormula(Func<float, float> Formula,Color colorL,float width)
    {
        this.formula = Formula;
        color = colorL;
        LineWidth = width;
    }
    public Vector2 GetResult(float x,float scale)
    {
        return new Vector2(x,formula(x/scale)*scale);
    }
}
public class FunctionGraphic : MaskableGraphic
{
    [Header("Line About Setting")]
    public FunctionBase funcBase = new FunctionBase();
    public IList<FunctionalFormula> FunctionList = new List<FunctionalFormula>();
    public void AddFunction(IList<FunctionalFormula> formuList)
    {
        foreach (FunctionalFormula formula in formuList)
            AddFunction(formula);
    }
    public void AddFunction(Func<float ,float> function,Color color1,float width)
    {
        FunctionalFormula formula = new global::FunctionalFormula(function, color1, width);
        AddFunction(formula);
    }
    public void AddFunction(FunctionalFormula formula)
    {
        FunctionList.Add(formula);
    }
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        var size = GetPixelAdjustedRect().size;
        var topLeft = new Vector2(-size.x / 2, size.y / 2);
        var topRight = new Vector2(size.x / 2, size.y / 2);
        var bottomLeft = new Vector2(-size.x / 2, -size.y / 2);
        var bottomRight = new Vector2(size.x / 2, -size.y / 2);

        #region Draw X axis
        var startPos = new Vector2(-size.x / 2, 0);
        var endPos = new Vector2(size.x / 2, 0);
        vh.AddUIVertexQuad(GetQuad(startPos, endPos, Color.red, funcBase.lineWidth));

        var firstPoint = new Vector2(size.x / 2, 0);
        var secondPoint = firstPoint + new Vector2(0, funcBase.arrowScale);
        var thirdPoint = firstPoint + new Vector2(Mathf.Sqrt(3) * funcBase.arrowScale, 0);
        var fourPoint = firstPoint + new Vector2(0, -funcBase.arrowScale);
        vh.AddUIVertexQuad(GetQuad(firstPoint, secondPoint, thirdPoint, fourPoint, Color.red));
        #endregion

        #region Draw Y Axis
        var bottomPos = new Vector2(0, -size.y / 2);
        var topPos = new Vector2(0, size.y / 2);
        vh.AddUIVertexQuad(GetQuad(bottomPos, topPos, Color.red, funcBase.lineWidth));
        var firstPos = topPos;
        var secondPos = new Vector3(-funcBase.arrowScale, size.y / 2);
        var thirdPos = new Vector3(0, size.y / 2 + Mathf.Sqrt(3) * funcBase.arrowScale);
        var fourPos = new Vector3(funcBase.arrowScale, size.y / 2);
        vh.AddUIVertexQuad(GetQuad(firstPos, secondPos, thirdPos, fourPos, Color.red));
        #endregion
        #region ShowScale
        if (funcBase.isShowScale)
        {
            for (var i = 1; i * funcBase.axisScale < size.x / 2; i++)
            {
                var StartPos = new Vector2(funcBase.axisScale * i, 0);
                vh.AddUIVertexQuad(GetQuad(StartPos, new Vector2(StartPos.x, funcBase.scaleLength), Color.red, 1.5f));
            }
            for (var i = 1; -funcBase.axisScale * i > -size.x / 2; i++)
            {
                var StartPos = new Vector2(-funcBase.axisScale * i, 0);
                vh.AddUIVertexQuad(GetQuad(StartPos, new Vector2(StartPos.x, funcBase.scaleLength), Color.red, 1.5f));
            }
            for (var i = 1; i * funcBase.axisScale < size.y / 2; i++)
            {
                var StartPos = new Vector2(0, i * funcBase.axisScale);
                vh.AddUIVertexQuad(GetQuad(StartPos, new Vector2(funcBase.scaleLength, StartPos.y), Color.red, 1.5f));
            }
            for (var i = 1; -i * funcBase.axisScale > -size.y / 2; i++)
            {
                var StartPos = new Vector2(0, -i * funcBase.axisScale);
                vh.AddUIVertexQuad(GetQuad(StartPos, new Vector2(funcBase.scaleLength, StartPos.y), Color.red, 1.5f));
            }
        }
        #endregion

        #region Draw FrameLine
                    switch (funcBase.lineType)
                    {
                        case LineType.FullLine:
                            for (var i = 1; i * funcBase.axisScale < size.x / 2; i++)
                            {
                                var StartPos = new Vector2(funcBase.axisScale * i, -size.y / 2);
                                var UpEndPos = new Vector2(StartPos.x, size.y / 2);
                                vh.AddUIVertexQuad(GetQuad(StartPos, UpEndPos, Color.white, funcBase.lineWidth));

                            }
                            for (var i = 1; -funcBase.axisScale * i > -size.x / 2; i++)
                            {
                                var StartPos = new Vector2(-funcBase.axisScale * i, -size.y / 2);
                                var UpEndPos = new Vector2(StartPos.x, size.y / 2);
                                vh.AddUIVertexQuad(GetQuad(StartPos, UpEndPos, Color.white, funcBase.lineWidth));

                            }
                            for (var i = 1; i * funcBase.axisScale < size.y / 2; i++)
                            {
                                var StartPos = new Vector2(-size.x / 2, i * funcBase.axisScale);
                                var rightEndPos = new Vector2(size.x / 2, StartPos.y);
                                vh.AddUIVertexQuad(GetQuad(StartPos, rightEndPos, Color.white, funcBase.lineWidth));

                            }
                            for (var i = 1; -i * funcBase.axisScale > -size.y / 2; i++)
                            {
                                var StartPos = new Vector2(-size.x / 2, -i * funcBase.axisScale);
                                var rightEndPos = new Vector2(size.x / 2, StartPos.y);
                                vh.AddUIVertexQuad(GetQuad(StartPos, rightEndPos, Color.white, funcBase.lineWidth));

                            }
                            break;
                        case LineType.LinaryLine:
                            {
                                for (var i = 1; i * funcBase.axisScale < size.x / 2; i++)
                                {
                                    var firstPointX = new Vector2(i * funcBase.axisScale, -size.y / 2);
                                    var secondPointx = new Vector2(firstPointX.x, size.y / 2);
                                    GetImageLinaryLine(ref vh, firstPointX, secondPointx, Color.gray, funcBase.lineLength, funcBase.spaceLength, funcBase.lineWidth);
                                }
                                for (var i = 1; -funcBase.axisScale * i > -size.x / 2; i++)
                                {
                                    var firstPointX = new Vector2(-i * funcBase.axisScale, -size.y / 2);
                                    var secondPointx = new Vector2(firstPointX.x, size.y / 2);
                                    GetImageLinaryLine(ref vh, firstPointX, secondPointx, Color.gray, funcBase.lineLength, funcBase.spaceLength, funcBase.lineWidth);
                                }
                                for (var i = 1; i * funcBase.axisScale < size.y / 2; i++)
                                {
                                    var firstPointX = new Vector2(-size.x / 2, i * funcBase.axisScale);
                                    var secondPointx = new Vector2(size.x / 2, firstPointX.y);
                                    GetImageLinaryLine(ref vh, firstPointX, secondPointx, Color.gray, funcBase.lineLength, funcBase.spaceLength, funcBase.lineWidth);
                                }
                                for (var i = 1; -i * funcBase.axisScale > -size.y / 2; i++)
                                {
                                    var firstPointX = new Vector2(-size.x / 2, -i * funcBase.axisScale);
                                    var secondPointx = new Vector2(size.x / 2, firstPointX.y);
                                    GetImageLinaryLine(ref vh, firstPointX, secondPointx, Color.gray, funcBase.lineLength, funcBase.spaceLength, funcBase.lineWidth);
                                }
                            }
                            break;
                    }
        #endregion
        if (FunctionList.Count <= 0) return;
        var unitPixel = 100 / funcBase.axisScale;
        foreach(var formula in FunctionList)
        {
            var startPoint= formula.GetResult(-size.x/2, funcBase.axisScale);
            for(var i=-size.x/2+1;i<size.x/2;i+= unitPixel)
            {
                var endPoint=formula.GetResult(i, funcBase.axisScale);
                vh.AddUIVertexQuad(GetQuad(startPoint,endPoint,formula.color,formula.LineWidth));
                startPoint = endPoint;
            }
           
        }
    }

    private UIVertex[] GetQuad(Vector2 startPos, Vector2 endPos, Color color0, float lineWidth = 2)
    {
        var dis = Vector2.Distance(startPos, endPos);
        float x = lineWidth * 0.5f * (endPos.y - startPos.y) / dis;
        float y = lineWidth * 0.5f * (endPos.x - startPos.x) / dis;
        if (x <= 0) x = -x;
        else y = -y;

        UIVertex[] vertexs = new UIVertex[4];
        vertexs[0].position = new Vector2(startPos.x + x, startPos.y + y);
        vertexs[1].position = new Vector2(endPos.x + x, endPos.y + y);
        vertexs[2].position = new Vector2(endPos.x - x, endPos.y - y);
        vertexs[3].position = new Vector2(startPos.x - x, startPos.y - y);

        for (int i = 0; i < vertexs.Length; i++)
        {
            vertexs[i].color = color0;
        }
        return vertexs;
    }
    private UIVertex[] GetQuad(Vector2 first, Vector2 second, Vector2 third, Vector2 four, Color color0)
    {
        UIVertex[] vertexs = new UIVertex[]
        {
            new UIVertex { position=first,color=color0,uv0=Vector2.zero},
            new UIVertex { position=second,color=color0,uv0=Vector2.zero},
            new UIVertex { position=third,color=color0,uv0=Vector2.zero},
            new UIVertex { position=four,color=color0,uv0=Vector2.zero}
        };
        return vertexs;

    }
    private void GetImageLinaryLine(ref VertexHelper vh,Vector2 startPos,Vector2 endPos,Color color0,float LineLength,float SpaceLength,float lineWidth=1.5f)
    {
        if(startPos.x.Equals(endPos.x))
        {
            
            var secondPoint =startPos+ new Vector2(0,LineLength);
            while(secondPoint.y<endPos.y)
            {
                vh.AddUIVertexQuad(GetQuad(startPos, secondPoint, color0, lineWidth));
                startPos = secondPoint + new Vector2(0, SpaceLength);
                secondPoint = startPos + new Vector2(0, LineLength);
                if(secondPoint.y>endPos.y)
                {
                    secondPoint = new Vector2(startPos.x,endPos.y);
                    vh.AddUIVertexQuad(GetQuad(startPos, secondPoint, color0, lineWidth));
                }
            }
        }
        if(startPos.y.Equals(endPos.y))
        {
            var secondPoint = startPos + new Vector2(LineLength,0);
            while(secondPoint.x<endPos.x)
            {
                vh.AddUIVertexQuad(GetQuad(startPos,secondPoint,color0, lineWidth));
                startPos = secondPoint + new Vector2(SpaceLength,0);
                secondPoint = startPos + new Vector2(LineLength,0);
                if(secondPoint.x>endPos.x)
                {
                    secondPoint = new Vector2(startPos.x,endPos.y);

                    vh.AddUIVertexQuad(GetQuad(startPos,secondPoint,color0, lineWidth));
                }
            }
        }
    }
}

效果图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值