Version: Unity 6.0 (6000.0)
语言 : 中文
UI 渲染器
在编辑器和运行时 UI 中创建饼图

生成 2D 视觉内容

可以使用网格 API 或矢量 API 将 2D 视觉内容生成到视觉元素上。

可以使用网格 API 来绘制自定义形状。网格 API 是高级用户的工具。如果只想生成简单的几何体,请改用矢量 API。矢量 API 受 HTML 画布的启发,绘制 2D 矢量图形,例如线条、弧形和形状。

使用网格 API

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

以下代码片段将生成单个四边形。它将分配顶点和索引,并提供顺时针方向的坐标:

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

使用矢量 API

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

要构建路径,需要发出命令来移动一种“虚拟笔”。例如,要生成网格 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 的属性控制线条的连接样式和端帽样式。

下图显示了不同的线条端帽样式和连接样式:

不同的线条端帽样式和连接样式
不同的线条端帽样式和连接样式

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

锯齿形线条
锯齿形线条
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 绘制带有边框的扇区:

具有边框的扇区
具有边框的扇区
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 在线条的角处绘制请求半径的弧形:

带弧形的线条
带弧形的线条
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 绘制贝塞尔曲线:

贝塞尔曲线
贝塞尔曲线
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 绘制二次曲线:

二次曲线
二次曲线
painter2D.BeginPath();
painter2D.MoveTo(new Vector2(100, 100));
painter2D.QuadraticCurveTo(new Vector2(150, 150), new Vector2(250, 100));
painter2D.Stroke();

填充中的孔

进行 Fill 时,可以构建带有孔的路径。调用 MoveTo 时,它会启动一个新的子路径。要创建孔洞,请使用填充规则使各种子路径彼此重叠。

填充规则决定了如何填充形状的内部:

  • OddEven:绘制一条射线,从该点向无限远的任何方向延伸,并计算射线穿过给定形状的路径段数。如果此数字为奇数,则点位于内部;如果为偶数,则点位于外部。
  • NonZero:绘制一条射线,从该点向无限远的任何方向延伸,然后检查形状的一段与射线相交的位置。从计数 0 开始,每次路径段从左到右穿过射线时都加一。每次路径段从右到左穿过射线时减一。计算交叉点后,如果结果为零,则点在路径之外。否则,在路径之内。

以下代码片段会创建一个带有菱形孔的矩形:

一个带有孔的矩形形状
一个带有孔的矩形形状
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 中创建饼图