Unity 6.3
0 онлайн 101 гостей 3 в системе
Вход
UI системы Шаг 202 из 317

Создание визуального контента 2D

Вы можете использовать сетку Сетка API или Painter2D для генерации визуального контента 2D на визуальном элементе.

Вы можете использовать Сетка API для рисования пользовательских форм. Сетка API является инструментом для продвинутых пользователей. Если вы хотите только генерировать простую геометрию, используйте вместо этого Vector API. Вдохновленный HTML Canvas, Vector API рисует 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);
    }
}

Используйте Painter2D API

Чтобы использовать Painter2D API, выберите объект Painter2D из MeshGenerationContext и создайте пути с его помощью. Затем вы можете использовать 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 создает прямую линию от текущего положения ручки до указанного положения. Перед тем, как нарисовать линии, определите свойства, такие как цвет хода, ширина линии, соединения и капли.

Когда вы рисуете линии, свойства ,LineJoin, и ,LineCap, управляют стилями соединений и концов линий.

На следующем рисунке показаны различные стили конца строки и соединения:

Различные стили заголовков и соединений строк
Различные стили заголовков и соединений строк

Следующий фрагмент кода рисует зигзагообразную линию:

Линия зигзага
Линия зигзага
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: Нарисуйте луч от этой точки до бесконечности в любом направлении, а затем проверьте места, где сегмент формы пересекает луч. Начните с подсчета нуля и добавляйте один каждый раз, когда сегмент пути пересекает луч слева направо. Вычитайте один каждый раз, когда сегмент пути пересекает луч справа налево. После подсчета пересечений, если результат равен нулю, то точка находится вне пути. В противном случае, она находится внутри.

Следующий фрагмент кода создает прямоугольник с отверстием в форме ромба:

Прямоугольник с отверстием
Прямоугольник с отверстием
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);

Дополнительные ресурсы