版本:Unity 6 (6000.0)
语言:English
UI 渲染器
在编辑器和运行时 UI 中创建饼图

生成 2D 视觉内容

您可以使用 Mesh API 或 Vector API 在视觉元素上生成 2D 视觉内容。

您可以使用 Mesh API 绘制自定义形状。 Mesh API 是一个面向高级用户的工具。如果您只想生成简单的几何图形,请改用 Vector API。受到 HTML Canvas 的启发,Vector API 绘制 2D 矢量图形,例如线条、弧线和形状。

使用 Mesh API

要使用 Mesh API,请使用 MeshGenerationContext.Allocate 方法分配网格,然后填充顶点和索引。 MeshGenerationContext.Allocate 方法分配并绘制指定数量的顶点和索引,这些顶点和索引是用来表示视觉元素内容的几何图形的。有关几何图形生成约定的详细信息,请参阅 Vertex.position

以下代码片段生成一个单个 quad。它分配顶点和索引,并按顺时针方向提供坐标

class QuadMeshElement : VisualElement
{
    public Color color = Color.red;

    public QuadMeshElement()
    {
        generateVisualContent += OnGenerateVisualContent;
    }

    void OnGenerateVisualContent(MeshGenerationContext mgc)
    {
        var mesh = mgc.Allocate(4, 6);

        var p0 = Vector2.zero;
        var p1 = new Vector2(layout.width, 0);
        var p2 = new Vector2(layout.width, layout.height);
        var p3 = new Vector2(0, layout.height);

        mesh.SetNextVertex(new Vertex() { position = new Vector3(p0.x, p0.y, Vertex.nearZ), tint = color });
        mesh.SetNextVertex(new Vertex() { position = new Vector3(p1.x, p1.y, Vertex.nearZ), tint = color });
        mesh.SetNextVertex(new Vertex() { position = new Vector3(p2.x, p2.y, Vertex.nearZ), tint = color });
        mesh.SetNextVertex(new Vertex() { position = new Vector3(p3.x, p3.y, Vertex.nearZ), tint = color });

        mesh.SetNextIndex(0);
        mesh.SetNextIndex(1);
        mesh.SetNextIndex(2);
        mesh.SetNextIndex(0);
        mesh.SetNextIndex(2);
        mesh.SetNextIndex(3);
    }
}

使用 Vector API

要使用 Vector API,请从 MeshGenerationContext 中访问 Painter2D 对象,并用它生成路径。然后,您可以使用 Stroke 绘制线条,或使用 Fill 绘制形状。

要构建路径,您发出移动一种“虚拟笔”的命令。例如,要生成 Mesh API 示例中的相同四边形,请将“笔”移动到第一个位置,并将线条链接在一起。完成路径后,使用 Fill 来构建形状。

class QuadVectorElement : VisualElement
{
    public Color color = Color.red;

    public QuadVectorElement()
    {
        generateVisualContent += OnGenerateVisualContent;
    }

    void OnGenerateVisualContent(MeshGenerationContext mgc)
    {
        var p0 = Vector2.zero;
        var p1 = new Vector2(layout.width, 0);
        var p2 = new Vector2(layout.width, layout.height);
        var p3 = new Vector2(0, layout.height);

        var painter2D = mgc.painter2D;

        painter2D.fillColor = color;

        painter2D.BeginPath();
        painter2D.MoveTo(p0);
        painter2D.LineTo(p1);
        painter2D.LineTo(p2);
        painter2D.LineTo(p3);
        painter2D.ClosePath();
        painter2D.Fill();
    }
}

线条

LineTo 方法从当前笔位置到提供的笔位置生成一条直线。在绘制线条之前,请定义属性,例如笔划颜色、线条宽度、连接和端点。

在绘制线条时,LineJoinLineCap 的属性控制线条连接和端点的样式。

下图说明了不同样式的线条端点和连接

Different styles of line caps and joins
不同样式的线条端点和连接

以下代码片段绘制一条锯齿线

A zigzag line
一条锯齿线
painter2D.lineWidth = 10.0f;
painter2D.strokeColor = Color.white;
painter2D.lineJoin = LineJoin.Round;
painter2D.lineCap = LineCap.Round;

painter2D.BeginPath();
painter2D.MoveTo(new Vector2(100, 100));
painter2D.LineTo(new Vector2(120, 120));
painter2D.LineTo(new Vector2(140, 100));
painter2D.LineTo(new Vector2(160, 120));
painter2D.LineTo(new Vector2(180, 100));
painter2D.LineTo(new Vector2(200, 120));
painter2D.LineTo(new Vector2(220, 100));
painter2D.Stroke();

弧线

您可以使用以下方法绘制弧线

  • Arc 方法从提供的弧线中心、半径以及起始角和结束角生成一条弧线。
  • ArcTo 方法在两条直线段之间生成一条弧线。

以下代码片段使用 Arc 绘制一个带有边框的扇形

A sector with a border
一个带有边框的扇形
painter2D.lineWidth = 2.0f;
painter2D.strokeColor = Color.red;
painter2D.fillColor = Color.blue;

painter2D.BeginPath();
// Move to the arc center
painter2D.MoveTo(new Vector2(100, 100));

// Draw the arc, and close the path
painter2D.Arc(new Vector2(100, 100), 50.0f, 10.0f, 95.0f);
painter2D.ClosePath();

// Fill and stroke the path
painter2D.Fill();
painter2D.Stroke();

以下代码片段使用 ArcTo 在线条拐角处绘制一个所需半径的弧线

A line with arc
一条带有弧线的线
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(100, 100));
painter2D.ArcTo(new Vector2(150, 150), new Vector2(200, 100), 20.0f);
painter2D.LineTo(new Vector2(200, 100));
painter2D.Stroke();

曲线

您可以使用以下方法绘制曲线

  • BezierCurveTo 方法使用两个控制点和三次贝塞尔曲线的最终位置生成一条三次贝塞尔曲线。
  • QuadraticCurveTo 方法使用一个控制点和二次贝塞尔曲线的最终位置生成一条二次贝塞尔曲线。

以下代码片段使用 BezierCurveTo 绘制一条贝塞尔曲线

A bezier curve
一条贝塞尔曲线
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(100, 100));
painter2D.BezierCurveTo(new Vector2(150, 150), new Vector2(200, 50), new Vector2(250, 100));
painter2D.Stroke();

以下代码片段使用 QuadraticCurveTo 绘制一条二次曲线

A quadratic curve
一条二次曲线
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(100, 100));
painter2D.QuadraticCurveTo(new Vector2(150, 150), new Vector2(250, 100));
painter2D.Stroke();

填充中的孔

在进行 Fill 时,您可以构建具有孔的路径。当您调用 MoveTo 时,它将启动一条新的子路径。要创建孔,请使用 填充规则 将各种子路径相互重叠。

填充规则 确定如何填充形状内部

  • OddEven:从该点向无限远处画一条射线,并计算该射线穿过给定形状的路径段数。如果这个数字是奇数,则该点在内部;如果是偶数,则该点在外部。
  • NonZero:从该点向无限远处画一条射线,然后检查形状的段与射线相交的位置。从零开始计数,每当路径段从左到右穿过射线时加一。每当路径段从右到左穿过射线时减一。计算完交叉点后,如果结果为零,则该点在路径外部。否则,它在内部。

以下代码片段创建一个矩形,其中有一个菱形孔

A rectangle shape with a hole in it
一个带有孔的矩形
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(10, 10));
painter2D.LineTo(new Vector2(300, 10));
painter2D.LineTo(new Vector2(300, 150));
painter2D.LineTo(new Vector2(10, 150));
painter2D.ClosePath();

painter2D.MoveTo(new Vector2(150, 50));
painter2D.LineTo(new Vector2(175, 75));
painter2D.LineTo(new Vector2(150, 100));
painter2D.LineTo(new Vector2(125, 75));
painter2D.ClosePath();

painter2D.Fill(FillRule.OddEven);

其他资源

UI 渲染器
在编辑器和运行时 UI 中创建饼图