Программирование

Как быстро изменить меш в Unity: копия + пакеты + воксели

Узнайте простые способы изменения меша в Unity: копирование меша, готовые пакеты Mesh Deformation и Dynamic Mesh Cutter, воксельный подход для дерева. Оптимизация.

Как игроку в Unity наиболее просто изменить модель игрового объекта, например, реализовать механику резьбы по дереву, создавая уникальные экземпляры? Какие простые и оптимизированные способы существуют, помимо использования шейдеров для скрытия полигонов?

В итоге
Самый простой способ — копировать исходный меш в коде, менять вершины в нужном месте, пересчитывать нормали и обновлять Mesh Collider. Для более сложных механик можно воспользоваться готовыми пакетами (Mesh Deformation, Dynamic Mesh Cutter) или построить систему из voxel‑ов с динамическими пересечениями. Всё это работает быстрее, чем простые шейдеры, и не требует скрытия полигонов.

Содержание


Копирование и редактирование меша в рантайме

  1. Создайте копию меша

    csharp
    MeshFilter mf = GetComponent<MeshFilter>();
    Mesh original = mf.sharedMesh;
    Mesh working = Instantiate(original);
    mf.mesh = working;          // Работать будем с копией
    

    Важно использовать Instantiate, а не менять sharedMesh, иначе вы измените оригинальный ассет.

  2. Найдите вершины, попадающие под «молоток»
    Обычно это Raycast‑проверка:

    csharp
    Ray ray = new Ray(handPosition, handForward);
    if (Physics.Raycast(ray, out RaycastHit hit, maxDistance))
    {
        Vector3[] verts = working.vertices;
        int[] tris = working.triangles;
    
        foreach (int i in tris)
        {
            Vector3 worldPos = mf.transform.TransformPoint(verts[i]);
            if ((worldPos - hit.point).magnitude < carveRadius)
                verts[i] += carveDirection * carveStrength;
        }
        working.vertices = verts;
    }
    

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

  3. Пересчитайте нормали и обновите коллайдер

    csharp
    working.RecalculateNormals();
    MeshCollider mc = GetComponent<MeshCollider>();
    mc.sharedMesh = null;          // Обновляем коллайдер
    mc.sharedMesh = working;
    

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

Показано в документации Unity о работе с Mesh APIUnity – Manual: Mesh


Пакетная реализация: Mesh Deformation и Dynamic Mesh Cutter

Mesh Deformation

Пакет из Asset Store позволяет быстро менять вершины на GPU, использует Burst Jobs и SIMD.

  • Преимущества:
    • Высокая производительность (до 60 fps на мобильных устройствах).
    • Встроенный буфер для хранения состояния.
    • Возможность «пластической» деформации, а не простого выреза.

Документация пакетаMesh Deformation Full Collection

Dynamic Mesh Cutter

Открытый репозиторий в GitHub, реализует скобку‑срез.

  • Как работает: перебирает треугольники, вычисляет пересечение плоскости, создаёт новые вершины и обновляет индексы.
  • Оптимизации:
    • Асинхронный разрез AsyncCutting в новых версиях.
    • Автоматическое масштабирование коллайдера.

Ссылка на репозиторийMeshSlicingRunTime


Воксельный подход к резьбе по дереву

  1. Соберите дерево из кубических вокселей (voxel grid)

    • Каждый воксель хранит состояние «полностью целый» или «уничтожен».
    • Используйте Marching Cubes для генерации поверхности.
  2. Врезка

    • Raycast‑проверка на вокселях: если луч пересекает воксель, меняем его состояние на «пустой».
    • Пересчитайте только те вершины, которые находятся на границе между состояниями.
  3. Преимущества

    • Простая логика «изъятие» без пересчёта всех треугольников.
    • Отлично подходит для деревьев, где форма меняется постепенно.

Пример реализацииGamedev Stackexchange: Cutting a desired shape out of a mesh


Оптимизация и лучшие практики

Практика Что делает Почему важно
Пул объектов (Object Pooling) Перезапускайте копии меша из пула, а не создавайте новые Снижает аллокацию памяти
Постепенные обновления Обновляйте только изменённые вершины Экономит вычислительные ресурсы
Параллелизм Используйте Burst и Jobs для расчётов вершин Ускоряет обработку больших мешей
Масштабирование коллайдера Пересчитайте коллайдер только после завершения всех изменений Предотвращает частые дорогостоящие пересчёты
LOD‑система Создавайте несколько версий меша разной детализации Снижает нагрузку на рендер и физику
GPU‑инстансинг Для множества одинаковых объектов используйте инстансинг Уменьшает draw‑calls

Подробности о LOD и обобщённые рекомендации по оптимизацииUnity – Manual: Preparing a character from scratch


Заключение

  1. Копия и редактирование меша – самый прямой путь, позволяющий быстро реализовать резьбу.
  2. Готовые пакеты (Mesh Deformation, Dynamic Mesh Cutter) ускоряют разработку и обеспечивают хорошую производительность.
  3. Воксельный подход даёт гибкость и простоту для объектов с постепенной деформацией, как дерево.
  4. Оптимизация (пул, LOD, Burst, правильное обновление коллайдера) критична для поддержания плавного FPS.

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

Источники

  1. Unity – Manual: Mesh
  2. Mesh Deformation Full Collection – Unity Asset Store
  3. MeshSlicingRunTime – GitHub
  4. Gamedev Stackexchange: Cutting a desired shape out of a mesh
  5. Unity – Manual: Preparing a character from scratch
  6. Habr: Манипуляция мешами в реальном времени на Unity
Авторы
Проверено модерацией
Модерация