Version: 5.3 (switch to 5.4b)
Using the Mesh Class
Оптимизация производительности графики

Пример - создание плоскости-биллборда

Для представления плоских поверхностей в Unity есть примитивы Plane и Quad (подробнее см. Примитивы. Однако полезно изучить то, как может быть построен минимальный меш плоскости, т.к. это, возможно, самой простой пример, с четырьмя вершинами для углов и двумя треугольниками.

В первую очередь, следует задать массив вершин. Предположим, что плоскость лежит на осях X и Y и путь её ширина и высота контролируются переменными-свойствами. Расположим вершины в таком порядке: нижняя-левая, нижняя-правая, верхняя-левая, верхняя-правая.

var vertices: Vector3[] = new Vector3[4];

vertices[0] = new Vector3(0, 0, 0);
vertices[1] = new Vector3(width, 0, 0);
vertices[2] = new Vector3(0, height, 0);
vertices[3] = new Vector3(width, height, 0);

mesh.vertices = vertices;

Т.к. свойства данных меша исполняют код “за кулисами”, будет куда более эффективно задать данные в собственном массиве, и затем назначить свойству, нежели получать доступ к свойству-массиву поэлементно.

Затем идут треугольники. Т.к. нам требуется 2 треугольника, каждый из которых определён тремя целыми числами, массив треугольников в общем счёте будет иметь 6 элементов. Помня о правиле упорядочивания углов по часовой стрелке, левый нижний треугольник будет использовать 0, 2, 1 в качестве индексов угла, в то время как другой (верхний правый) будет использовать 2, 3, 1.

var tri: int[] = new int[6];

//  Lower left triangle.
tri[0] = 0;
tri[1] = 2;
tri[2] = 1;

//  Upper right triangle.   
tri[3] = 2;
tri[4] = 3;
tri[5] = 1;

mesh.triangles = tri;

Меш состоящий только из вершин и треугольников будет виден в редакторе, но будет выглядеть не очень убедительно, т.к. он не будет нормально закрашен без нормалей. Нормали для плоскости поверхности очень просты - они все одинаковы и направлены в отрицательном сторону оси Z в локальном пространстве плоскости. С добавленными нормалям, плоскость будет закрашиваться корректно, но помните, что вам нужен источник света в сцене, чтобы увидеть этот эффект.

var normals: Vector3[] = new Vector3[4];

normals[0] = -Vector3.forward;
normals[1] = -Vector3.forward;
normals[2] = -Vector3.forward;
normals[3] = -Vector3.forward;

mesh.normals = normals;

Наконец, добавление текстурных координат в меш позволит ему правильно отображать материал. Предполагая, что мы хотим увидеть всё изображение на плоскости, все значения UV будут равны 0 или 1, в соответствии с углами текстуры.

var uv: Vector2[] = new Vector2[4];

uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(1, 0);
uv[2] = new Vector2(0, 1);
uv[3] = new Vector2(1, 1);

mesh.uv = uv;

Завершенный скрипт может выглядеть как-то так:-

var width: float;
var height: float;

function Start() {  
    var mf: MeshFilter = GetComponent.<MeshFilter>();
    var mesh = new Mesh();
    mf.mesh = mesh;
    
    var vertices: Vector3[] = new Vector3[4];
    
    vertices[0] = new Vector3(0, 0, 0);
    vertices[1] = new Vector3(width, 0, 0);
    vertices[2] = new Vector3(0, height, 0);
    vertices[3] = new Vector3(width, height, 0);
    
    mesh.vertices = vertices;
    
    var tri: int[] = new int[6];

    tri[0] = 0;
    tri[1] = 2;
    tri[2] = 1;
    
    tri[3] = 2;
    tri[4] = 3;
    tri[5] = 1;
    
    mesh.triangles = tri;
    
    var normals: Vector3[] = new Vector3[4];
    
    normals[0] = -Vector3.forward;
    normals[1] = -Vector3.forward;
    normals[2] = -Vector3.forward;
    normals[3] = -Vector3.forward;
    
    mesh.normals = normals;
    
    var uv: Vector2[] = new Vector2[4];

    uv[0] = new Vector2(0, 0);
    uv[1] = new Vector2(1, 0);
    uv[2] = new Vector2(0, 1);
    uv[3] = new Vector2(1, 1);
    
    mesh.uv = uv;
}

Учтите, что если код был запущен один раз в функции Start, то меш не изменится на протяжении всей игры. Тем не менее, вы можете просто поместить код в функцию Update, тем самым позволив мешу меняться каждый кадр (хотя это может изрядно увеличить нагрузку на CPU).

Using the Mesh Class
Оптимизация производительности графики