Unity如何画曲线?网格绘制贝塞尔曲线

原理

一般的Image Mesh为一个矩形区域,它的顶点数为4是固定在四个角的,所以我们能看到的是个矩形图。
在这里插入图片描述
为了让Image产生弯曲的效果,我们就是增加Mesh中矩形区域的数量,并且使其按一定的曲线排列。
最终达到曲线的效果。
在这里插入图片描述
这里使用的曲线为贝塞尔曲线,这种曲线非常灵活,可扩展,达到理想的效果。
脚本如下:

using UnityEngine;
using UnityEngine.UI;

public class BezierMeshImage : Image 
{
    //控制点坐标
    Vector2 controlV2 = new Vector2(0,200);
    //密集度 mesh数量
    int intensity = 50;
    //mesh 宽度 
    int width = 8;
    // 以上属于动态配置参数,为了方便共享才放在此中,建议使用时提取出去动态配置。

    float halfW;
    Vector3[] bezierPoints;
    protected override void Start()
    {
        base.Start();
        halfW = width/2;
    }
    public void UpdateBezierPoints(Vector3 start, Vector3 end, Vector3 control, int segmentNum)
    {
        bezierPoints = Bezier.GetPointList(start, end, control, segmentNum);
    }
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        var r = GetPixelAdjustedRect();
        var v = new Vector4(r.x, r.y, r.x + r.width, r.y + r.height);

        var start = new Vector3(v.x,v.y + r.height/2,1);
        var end = new Vector3(v.z,v.y + r.height/2,1);
        var c = new Vector3(controlV2.x,controlV2.y);
        UpdateBezierPoints(start,end,c,intensity);

        vh.Clear();
        for (int index=0; index < bezierPoints.Length; index++)
        {
            Vector3 baseVector = bezierPoints[index];
            var i = index*4;
            vh.AddVert(baseVector+new Vector3(-halfW,-halfW,1), color, new Vector2(0f, 0f));
            vh.AddVert(baseVector+new Vector3(-halfW,halfW,1), color, new Vector2(0f, 1f));
            vh.AddVert(baseVector+new Vector3(halfW,halfW,1), color, new Vector2(1f, 1f));
            vh.AddVert(baseVector+new Vector3(halfW,-halfW,1), color, new Vector2(1f, 0f));
            vh.AddTriangle(i,i+1,i+2);
            vh.AddTriangle(i+2, i+ 3,i);
        }
    }
}

public static class Bezier
{
    private static Vector3 CalculatePoint(float t, Vector3 p0, Vector3 p1, Vector3 p2)
    {
        float u = 1 - t;
        float tt = t * t;
        float uu = u * u;
        var p = uu * p0;
        p += 2 * u * t * p1;
        p += tt * p2;
        return p;
    }
    public static Vector3[] GetPointList(Vector3 startPoint, Vector3 endPoint,Vector3 cPoint,int segmentNum)
    {
        Vector3[] path = new Vector3[segmentNum];
        for (int i = 1; i <= segmentNum; i++)
        {
            float t = i / (float)segmentNum;
            Vector3 pixel = CalculatePoint(t, startPoint,cPoint,endPoint);
            path[i - 1] = pixel;
        }
        return path;
    }
}
原创文章 28 获赞 30 访问量 2422

猜你喜欢

转载自blog.csdn.net/qq_28820675/article/details/105740004