Unity 6.3
0 онлайн 106 гостей 3 в системе
Вход
Ассеты и медиа Шаг 35 из 148

Создание четырехмерной сетки с помощью скрипта

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

Примечание: Unity обрабатывает и отображает геометрию в треугольниках, а не в четырехугольниках. Это означает, что примитив Quad состоит из двух треугольников.

Вершинный массив

Первое, что вам нужно сделать, это настроить массив вершин, которые использует ваша форма.

В этом примере предполагается, что четырёхугольник лежит на осях x и y, и что ваш скрипт содержит переменные width и height.

Vector3[] 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;

В этом примере вершины представлены в следующем порядке:

  1. Внизу слева
  2. Внизу справа
  3. Верхний левый
  4. Вверху справа

Из-за способа, которым Unity извлекает свойства данных Mesh, гораздо эффективнее настроить данные в собственном массиве, а затем назначить массив свойству (например, Mesh.vertices или Mesh.normals), чем получать доступ к массиву свойств через отдельные элементы.

Треугольники

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

int[] tris = new int[6]
{
    // lower left triangle
    0, 2, 1,
    // upper right triangle
    2, 3, 1
};
mesh.triangles = tris;

Нормы

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

Vector3[] normals = new Vector3[4]
{
    -Vector3.forward,
    -Vector3.forward,
    -Vector3.forward,
    -Vector3.forward
};
mesh.normals = normals;

Если вы не хотите определять нормы сами, вы можете использовать Mesh.RecalculateNormals().

Координаты текстуры

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

Vector2[] uv = new Vector2[4]
{
      new Vector2(0, 0),
      new Vector2(1, 0),
      new Vector2(0, 1),
      new Vector2(1, 1)
};
mesh.uv = uv;

Окончательный скрипт

Следующий скрипт объединяет все вышеизложенное для создания квада в вашем Scene. Чтобы использовать его:

  1. Создайте новый скрипт C# (меню: Ассеты > Создать > MonoBehaviour Script) и дайте ему имя QuadCreator.
  2. Откройте скрипт QuadCreator, скопируйте в него примерный код и сохраните скрипт.
  3. Вернувшись в Редактор, создайте новый GameObject в вашем Scene (меню: GameObject > Создать пустой).
  4. В Inspector, выберите Добавить компонент > Сценарии > Quad Creator.
  5. Поместите GameObject туда, где вы хотите в Scene.
  6. Если вы не можете увидеть квадрант в представлении Scene или Game, убедитесь, что вы смотрите его с правильной стороны; Unity не рендирует заднюю поверхность этой сетки.
using UnityEngine;

public class QuadCreator : MonoBehaviour
{
    public float width = 1;
    public float height = 1;

    public void Start()
    {
        MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
        meshRenderer.sharedMaterial = new Material(Shader.Find("Standard"));

        MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();

        Mesh mesh = new Mesh();

        Vector3[] 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;

        int[] tris = new int[6]
        {
            // lower left triangle
            0, 2, 1,
            // upper right triangle
            2, 3, 1
        };
        mesh.triangles = tris;

        Vector3[] normals = new Vector3[4]
        {
            -Vector3.forward,
            -Vector3.forward,
            -Vector3.forward,
            -Vector3.forward
        };
        mesh.normals = normals;

        Vector2[] uv = new Vector2[4]
        {
            new Vector2(0, 0),
            new Vector2(1, 0),
            new Vector2(0, 1),
            new Vector2(1, 1)
        };
        mesh.uv = uv;

        meshFilter.mesh = mesh;
    }
}

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