Меши 2D: вершины, индексы и UV
Собрать ArrayMesh и отобразить его через MeshInstance2D без внешней модели.
Когда нужен меш
MeshInstance2D показывает геометрию ресурса Mesh в canvas. ArrayMesh позволяет явно задать вершины, треугольники и UV. Для прямоугольной картинки обычно проще Sprite2D; меш полезен, когда нужна своя топология, форма или согласованные данные вершин.
Наличие Mesh не создаёт коллизию, световой заслонитель или навигацию. Эти данные задаются отдельно. Для обычного многоугольника сравните также Polygon2D: меньше кода не всегда требует собственных массивов.
Запустить минимальный пример
Нужен C#-проект Reckfell.NET.Sdk 1.0.0, net10.0. Сохраните два файла ниже, выполните dotnet build, прикрепите CanvasAaExample.cs к корню Entity2D уровня .rscene и запустите. По центру Viewport появится белый треугольник. Antialiasing оставьте Disabled для первого запуска; различия рендереров описаны в сглаживании.
CanvasMeshes.cs
using System;
using Reckfell;
public static class CanvasMeshes
{
public static ArrayMesh Quad(Vector2 size)
{
if (!size.IsFinite() || size.X <= 0 || size.Y <= 0)
throw new ArgumentOutOfRangeException(nameof(size));
Vector2 half = size * 0.5f;
return Build(
new[] { new Vector2(-half.X, -half.Y), new Vector2(half.X, -half.Y), half, new Vector2(-half.X, half.Y) },
new[] { Vector2.Zero, Vector2.Right, Vector2.One, Vector2.Down },
new[] { 0, 1, 2, 0, 2, 3 });
}
public static ArrayMesh Triangle() => Build(
new[] { new Vector2(-45, -40), new Vector2(50, -17), new Vector2(-20, 45) },
new[] { Vector2.Zero, Vector2.Right, Vector2.Down },
new[] { 0, 1, 2 });
private static ArrayMesh Build(Vector2[] vertices, Vector2[] uv, int[] indices)
{
var arrays = new Reckfell.Collections.Array();
arrays.Resize((int)Mesh.ArrayType.Max);
arrays[(int)Mesh.ArrayType.Vertex] = vertices;
arrays[(int)Mesh.ArrayType.TexUV] = uv;
arrays[(int)Mesh.ArrayType.Index] = indices;
var mesh = new ArrayMesh();
mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
return mesh;
}
}CanvasAaExample.cs
using Reckfell;
public partial class CanvasAaExample : Entity2D
{
[Export] public Viewport.Msaa Antialiasing { get; set; } = Viewport.Msaa.Disabled;
public override void _Ready()
{
GetViewport().Msaa2D = Antialiasing;
AddChild(new MeshInstance2D
{
Mesh = CanvasMeshes.Triangle(),
Position = GetViewportRect().Size * 0.5f + new Vector2(0.3f, 0.2f),
Rotation = 0.17f,
Material = new CanvasItemMaterial { LightMode = CanvasItemMaterial.LightModeEnum.Unshaded }
});
}
}Разобрать массивы
| Массив | Что содержит |
|---|---|
| Vertex | Локальные Vector2; начало координат и позиция Entity — разные вещи |
| TexUV | По одной координате выборки текстуры на вершину |
| Index | Номера вершин, объединённые по три в треугольники |
В Quad четыре вершины и шесть индексов: (0,1,2) и (0,2,3). Это два треугольника, которые делят общие вершины. Для Triangle достаточно трёх вершин и трёх индексов. Массив слотов сначала расширяется до Mesh.ArrayType.Max; не заменяйте его обычным списком только заполненных атрибутов.
Vector2[] в слоте Vertex задаёт 2D-формат. Не добавляйте лишнюю Z-компоненту ради названия ArrayMesh. Цвет из примера берётся из обычного canvas-материала; Texture не нужна для белого силуэта. Чтобы показать изображение, задайте MeshInstance2D.Texture и согласуйте UV с нужным регионом. Здесь UV лежат в диапазоне 0..1 и являются координатами выборки, а не пикселями текстуры.
При собственных данных длина массива UV должна соответствовать числу вершин, а индексы — попадать в диапазон [0, число вершин). Суммарное число индексов для списка треугольников должно делиться на три. Топология и корректные атрибуты важнее предположения «три точки всегда дадут нужную картинку».
Изменять и переиспользовать
Quad проверяет конечные положительные размеры до создания ресурса. Для своего генератора аналогично проверяйте входы до AddSurfaceFromArrays. Этот вызов добавляет surface, а не заменяет предыдущую. При пересборке создайте новый Mesh либо осознанно очистите прежние surfaces; изменение общего ресурса затронет использующие его экземпляры.
Position, Rotation и Scale MeshInstance2D преобразуют готовую геометрию. Для простого перемещения не пересоздавайте вершины каждый кадр. Изменение локального массива C# после загрузки surface не является автоматическим обновлением GPU-данных; используйте предусмотренные методы обновления или пересборку ресурса.
Если ничего не видно
- Проверьте Mesh, наличие surface, непустой Vertex и корректный Index.
- Проверьте локальные координаты: геометрия может находиться за пределами Viewport.
- Проверьте Visible, Modulate.A, ZIndex и материал.
- Если ожидаете текстуру, проверьте Texture и соответствующие UV; индексы не являются UV.
- Если ожидаете столкновение, создайте физическую форму отдельно.