首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >UI绘制

UI绘制

作者头像
bering
发布2019-12-02 14:00:33
1.6K0
发布2019-12-02 14:00:33
举报
文章被收录于专栏:游戏开发之旅游戏开发之旅

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/CJB_King/article/details/78690250

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));
                }
            }
        }
    }
}

效果图:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档