Пример - создание плоскости-биллборда
Для представления плоских поверхностей в Unity есть примитивы Plane и Quad (подробнее см. Примитивы. Однако полезно изучить то, как может быть построен минимальный меш плоскости, т.к. это, возможно, самой простой пример, с четырьмя вершинами для углов и двумя треугольниками.
В первую очередь, следует задать массив вершин. Предположим, что плоскость лежит на осях X и Y и путь её ширина и высота контролируются переменными-свойствами. Расположим вершины в таком порядке: нижняя-левая, нижняя-правая, верхняя-левая, верхняя-правая.
var vertices = new Vector3[4]
{
new Vector3(0, 0, 0),
new Vector3(width, 0, 0),
new Vector3(0, height, 0),
new Vector3(width, height, 0)
};
mesh.vertices = vertices;
Т.к. свойства данных меша исполняют код “за кулисами”, будет куда более эффективно задать данные в собственном массиве, и затем назначить свойству, нежели получать доступ к свойству-массиву поэлементно.
Затем идут треугольники. Т.к. нам требуется 2 треугольника, каждый из которых определён тремя целыми числами, массив треугольников в общем счёте будет иметь 6 элементов. Помня о правиле упорядочивания углов по часовой стрелке, левый нижний треугольник будет использовать 0, 2, 1 в качестве индексов угла, в то время как другой (верхний правый) будет использовать 2, 3, 1.
var tris = new int[6]
{
// lower left triangle
0, 2, 1,
// upper right triangle
2, 3, 1
};
mesh.triangles = tris;
Меш состоящий только из вершин и треугольников будет виден в редакторе, но будет выглядеть не очень убедительно, т.к. он не будет нормально закрашен без нормалей. Нормали для плоскости поверхности очень просты - они все одинаковы и направлены в отрицательном сторону оси Z в локальном пространстве плоскости. С добавленными нормалям, плоскость будет закрашиваться корректно, но помните, что вам нужен источник света в сцене, чтобы увидеть этот эффект.
var normals = new Vector3[4]
{
-Vector3.forward,
-Vector3.forward,
-Vector3.forward,
-Vector3.forward
};
mesh.normals = normals;
Наконец, добавление текстурных координат в меш позволит ему правильно отображать материал. Предполагая, что мы хотим увидеть всё изображение на плоскости, все значения UV будут равны 0 или 1, в соответствии с углами текстуры.
var uv = new Vector2[4]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1)
};
mesh.uv = uv;
Завершенный скрипт может выглядеть как-то так:-
using UnityEngine;
public class CreateBillboard : MonoBehaviour
{
public float width = 1;
public float height = 1;
public void Start()
{
var mf = GetComponent<MeshFilter>();
var mesh = new Mesh();
mf.mesh = mesh;
var vertices = new Vector3[4]
{
new Vector3(0, 0, 0),
new Vector3(width, 0, 0),
new Vector3(0, height, 0),
new Vector3(width, height, 0)
};
mesh.vertices = vertices;
var tris = new int[6]
{
// lower left triangle
0, 2, 1,
// upper right triangle
2, 3, 1
};
mesh.triangles = tris;
var normals = new Vector3[4]
{
-Vector3.forward,
-Vector3.forward,
-Vector3.forward,
-Vector3.forward
};
mesh.normals = normals;
var uv = new Vector2[4]
{
new Vector2(0, 0),
new Vector2(1, 0),
new Vector2(0, 1),
new Vector2(1, 1)
};
mesh.uv = uv;
}
}
Учтите, что если код был запущен один раз в функции Start, то меш не изменится на протяжении всей игры. Тем не менее, вы можете просто поместить код в функцию Update, тем самым позволив мешу меняться каждый кадр (хотя это может изрядно увеличить нагрузку на CPU).