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

Работа с векторной графикой

Векторная графика — это масштабируемая графика, независимая от разрешения, которую вы можете использовать в UI. Они определяются математическими уравнениями, а не пикселями, что позволяет им сохранять качество при любом размере.

Импорт и использование векторной графики

Вы можете импортировать векторную графику для использования в вашем UI.

При импорте векторного изображения установите его Генерированный Тип Актива на UI Toolkit Векторное Изображение в Inspector для получения наилучших результатов. Это создает специализированный ассет, разработанный исключительно для использования в UI Toolkit, например в UI Builder или для времени выполнения UI.

В качестве альтернативы, вы можете установить его Тип Созданного Актива на Texture2D для использования в других контекстах.

Дополнительные сведения см. в Настройки импорта векторных изображений и Установка фонового изображения.

Ограничения

Работая с векторной графикой, помните о следующих ограничениях:

  • Не запускайте Unity с аргументом командной строки -no-graphics, так как это может помешать импорту векторных изображений SVG.

  • Импортер SVG поддерживает подмножество спецификации SVG 1.1. В настоящее время не поддерживаются следующие функции:

    • Текстовые элементы
    • Маскировка по пикселям
    • Эффекты фильтров
    • Интерактивные возможности
    • Анимации

Создание векторной графики с помощью C# скриптов

Вы можете создавать и манипулировать векторной графикой с помощью C# скриптов в вашем UI. Unity предоставляет набор классов и методов, которые позволяют:

  • Создание векторных графических элементов, таких как пути и формы.
  • Применение заполнений и градиентов к формам.
  • Клип содержимого, используя другие формы, как клиперы.
  • Тесселяция и рендер векторной графики в меши, спрайты или текстуры для отображения в вашем UI.

Существует два основных вида рисуемых экземпляров: пути и формы.

Пути

Пути представляют собой векторные формы, определяемые последовательностью кубических кривых Безье, сгруппированных в BezierContour. Каждый контур состоит из массива сегментов пути и флага, указывающего, закрыт ли контур. Вы можете использовать их для создания сложных, непрерывных кривых для вашей графики UI.

Каждый сегмент траектории определяет начальную точку и две контрольные точки. Начальная точка следующего сегмента продолжает кривую, что позволяет соединить несколько сегментов для создания гладкой, непрерывной формы. Для правильного контура требуется по крайней мере два сегмента.

Например, рассмотрим следующий путь:

Контур
Контур

Чтобы создать траекторию, определите список сегментов и укажите, закрывать ли контур. Затем вы можете назначить свойства хода и заполнения для стилизации траектории по мере необходимости.

var a = new Vector2(0, 0);
var b = new Vector2(100, 0);
var c = new Vector2(100, 100);
var d = new Vector2(0, 100);
var e = new Vector2(50, 50);
var f = new Vector2(150, 50);
var g = new Vector2(200, 0);

var segments = new BezierPathSegment[] {
    new BezierPathSegment() { P0 = a, P1 = b, P2 = c },
    new BezierPathSegment() { P0 = d, P1 = e, P2 = f },
    new BezierPathSegment() { P0 = g }
};
var path = new Shape()
{
    Contours = new BezierContour[]
    {
        new BezierContour()
        {
            Segments = segments,
            Closed = true
        }
    },
    PathProps = new PathProperties()
    {
        Stroke = new Stroke() { Color = Color.red, HalfThickness = 1.0f }
    }
};

Когда вы определяете BezierContour с Closed = true, контур соединяет последний сегмент пути с первым сегментом пути. Последний сегмент пути использует свои значения P1 и P2 в качестве точек управления.

Формы

Формы похожи на траектории, но могут содержать множество контуров и поддерживать заполнение. Вы можете заполнять формы сплошными цветами, текстурами или градиентами и применять преобразования к заполнению. Это позволяет создавать сложные, заполненные векторные графики для вашего UI.

Можно использовать различные типы заполнения:

Градиенты

Градиентные заполнения позволяют смешивать несколько цветов вместе, либо по прямой линии (линейные), либо радиально от точки (радиальные). Градиент определяется путем указания типа и серии цветовых остановок, каждая из которых имеет цвет и процент вдоль градиента.

Например, вы можете создать линейный градиент, который переходит от синего к красному и желтому, определив остановки на 0%, 50% и 100%:

var gradient = new GradientFill()
{
    Type = GradientFillType.Linear,
    Stops = new GradientStop[] {
        new GradientStop() { Color = Color.blue, StopPercentage = 0.0f },
        new GradientStop() { Color = Color.red, StopPercentage = 0.5f },
        new GradientStop() { Color = Color.yellow, StopPercentage = 1.0f }
    }
};
Линейное заполнение
Линейное заполнение

Режимы адресации градиента и определяют, как Unity отображает цвет, когда координаты градиента выходят за пределы диапазона, как показано здесь:

Режимы адресации
Режимы адресации

Режим заполнения

Режим заполнения определяет, как рассчитывается внутренняя поверхность сложных форм и отверстий. Основными режимами заполнения являются:

  • NonZero: Определяет, находится ли точка внутри фигуры, посчитывая, сколько раз контур траектории обходит эту точку. Если результат не равен нулю, то считается, что точка находится внутри. Направление каждого контура (по часовой стрелке или против часовой стрелки) влияет на результат.

    NonZero заполнить
    NonZero заполнить
  • OddEven: Подсчитывает, сколько раз горизонтальная линия от точки пересекает контуры формы. Если число пересечений нечетно, то точка находится внутри, если чётно, то она находится снаружи. Этот режим часто используется для форм с отверстиями.

    EvenOdd заполнить
    EvenOdd заполнить

Выберите режим заполнения, который лучше всего соответствует желаемому виду ваших векторных форм, особенно при работе с перекрывающимися путями или отверстиями.

Клиппинг

SceneNode класс включает Clipper свойство, которое позволяет вам обрезать содержимое узла с помощью формы.

Клиппер
Клиппер

В следующем примере кода создается эллипс, который обрезает узор из повторяющихся квадратов:

// Create an ellipse shape to use as the clipper
var ellipseShape = new Shape();
VectorUtils.MakeEllipseShape(ellipseShape, new Vector2(0, 0), 50, 100);

var ellipseClipper = new SceneNode
{
    Shapes = new List<Shape> { ellipseShape }
};

// Create a pattern for clipping, for example, repeating squares
var squaresPattern = new SceneNode
{
    Shapes = new List<Shape>() // Add your fill pattern here
};

// Create a SceneNode that applies the clipper to its children
var clippedNode = new SceneNode
{
    Children = new List<SceneNode> { squaresPattern },
    Clipper = ellipseClipper
};

Примечание: Используйте только фигуры в качестве клипперов. Процесс обрезки игнорирует любые штриховые изображения, которые вы определили на фигуре клиппера. Вы можете обрезать любую комбинацию фигур и штриховых изображений как содержание.

Предупреждение: Обрезка может быть вычислительно дорогостоящей. Хотя обрезка простых фигур с помощью простого клиппера обычно эффективна, использование сложных фигур или клипперов может значительно повлиять на производительность.

Рендирование векторной графики

Чтобы отобразить элементы векторной графики на экране, сначала получите тесселлированную (триангуляцию) версию сцены. Когда вы настроили экземпляр VectorScene, вы можете тесселлировать его следующим методом VectorUtils:

var geometry = VectorUtils.TessellateScene(
    scene,
    new VectorUtils.TessellationOptions()
    {
        StepDistance = 10.0f,
        MaxCordDeviation = 0.1f,
        MaxTanAngleDeviation= 0.1f
    });

Примечание: Вы должны указать maxTanAngleDeviation в радианах.

Чтобы отключить ограничение maxCordDeviation, установите его на float.MaxValue. Чтобы отключить ограничение maxTanAngleDeviation, установите его на Mathf.PI/2.0f.

Отключение ограничений ускоряет тесселляцию, но может генерировать больше вершин.

Полученный список объектов Geometry содержит все вершины и сопутствующую информацию, необходимую для правильного отображения сцены.

Атлас текстур и градиентов

Если сцена имеет какие-либо текстуры или градиенты, вы должны создать атлас текстур и заполнить UVs геометрии. Эти методы являются частью VectorUtils class:

var atlas = VectorUtils.GenerateAtlasAndFillUVs(geoms, 16);

Метод GenerateAtlas является дорогостоящей операцией, так что кэшируйте полученный объект Texture2D, когда это возможно. Вам нужно восстанавливать атлас только тогда, когда текстура или градиент изменяются внутри сцены.

Когда вершины изменяются внутри геометрии, вызов метода FillUVs, который является дешевым.

Нарисовать мозаику сцены

Вы можете отобразить геометрию несколькими способами. Например, вы можете отобразить геометрию следующим образом:

  • Заполнение ассета Mesh
  • Создание ассета Sprite
  • Использование низкоуровневой графической библиотеки Unity

Для любого из этих методов, используйте предоставленные материалы для рисования векторной графики с тесселяцией.

Чтобы заполнить элемент сетки, используйте следующий метод VectorUtils:

var mesh = new Mesh();
VectorUtils.FillMesh(
    mesh, 
    geoms,
    100.0f, // svgPixelsPerUnit
    false); // flipYAxis

Чтобы создать ресурс спрайта, используйте следующий метод VectorUtils:

var sprite = VectorUtils.BuildSprite(
    geoms,
    100.0f,                       // svgPixelsPerUnit
    VectorUtils.Alignment.Center, // alignment
    Vector2.zero,                 // pivot
    16,                           // gradient resolution
    false);                       // flipYAxis

Чтобы отобразить спрайт в Texture2D, используйте следующий метод VectorUtils:

var tex = VectorUtils.RenderSpriteToTexture2D(
    sprite,          // The sprite to draw
    256, 256,       // The texture dimensions
    null,           // The material to use ("Unlit_Vector" or "Unlit_VectorGradient")
    1);             // The number of samples per pixel

Чтобы отобразить сгенерированный спрайт в режиме немедленного отображения GL команды, используйте RenderSprite метод в VectorUtils класс, чтобы отрисовать спрайт в единичном квадрате (прямоугольнике между 0 и 1 по осям X и Y):

// Or "Hidden/VectorGraphics/VectorGradient" for gradients
var mat = new Material(Shader.Find("Hidden/VectorGraphics/Vector"));

VectorUtils.RenderSprite(
    sprite,  // The sprite to draw
    mat);    // The material to use ("Unlit_Vector" or "Unlit_VectorGradient")

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