← Назад к вопросам

Приведи пример когда вызывается перестройка Mesh на Canvas

2.0 Middle🔥 171 комментариев
#UI#Оптимизация

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Отличный вопрос! Он затрагивает важный аспект производительности UI в Unity. Перестройка меша (Mesh) на Canvas — это процесс, при котором система Unity UI (uGUI) заново генерирует геометрию (вертексы и треугольники) для отрисовки всех графических элементов. Это дорогостоящая операция, и её необоснованные вызовы — частая причина просадок FPS.

Когда происходит перестройка меша Canvas?

Перестройка вызывается при любом изменении, которое влияет на внешний вид или геометрию UI-элемента. Система помечает Canvas как "грязный" (dirty), и в конце текущего или начале следующего кадра происходит пересчёт.

Основные триггеры:

1. Изменение свойств Render-компонентов

Любое изменение, затрагивающее то, как элемент рисуется.

  • Image: изменение спрайта (sprite), цвета (color), материала (material), типа изображения (Image Type — например, с Simple на Sliced).
  • Text / TextMeshPro: изменение текста (text), шрифта (font), размера шрифта (fontSize), стиля (жирный, курсив), цвета, параметров выравнивания. Изменение текста — самый частый виновник!
  • RawImage: изменение текстуры (texture).
  • Mask / RectMask2D: изменение размеров или включение/выключение маски.

2. Изменение трансформации или состояния видимости

  • Изменение RectTransform: position, rotation, scale, sizeDelta, pivot, anchor. Даже если размер меняется из-за работы Content Size Fitter или Layout Group.
  • Включение (SetActive(true)) или отключение GameObject с UI-элементом.
  • Изменение свойства enabled у компонента, влияющего на отрисовку (например, у Image).

3. Действия системы компоновки (Layout System)

Layout Group (Horizontal, Vertical, Grid) и Content Size Fitter вызывают перестройку не только своего меша, но и мешей дочерних элементов, так как пересчитывают их позиции и размеры.

  • Добавление/удаление дочернего элемента.
  • Изменение размера дочернего элемента (которое, в свою очередь, может быть вызвано его собственным контентом).

Практический пример: Текст с часто меняющимся значением

Давайте рассмотрим классический антипаттерн, который приводит к множественным перестройкам каждый кадр, и затем оптимизированное решение.

❌ Плохой пример (вызовет перестройку каждый кадр):

using UnityEngine;
using UnityEngine.UI;

public class BadPerformanceCounter : MonoBehaviour
{
    public Text counterText; // Стандартный Text (uGUI)
    private float timer = 0f;
    private int count = 0;

    void Update()
    {
        timer += Time.deltaTime;
        if (timer >= 0.1f) // Меняем текст 10 раз в секунду
        {
            timer = 0;
            count++;
            // ЭТА СТРОКА ВЫЗЫВАЕТ ПЕРЕСТРОЙКУ МЕША КАЖДЫЙ РАЗ!
            counterText.text = "Count: " + count.ToString();
        }
    }
}

В этом коде свойство .text компонента Text обновляется 10 раз в секунду. Каждое обновление заставляет Canvas, содержащий этот Text, полностью перестраивать свой меш. Если на Canvas много других элементов, они тоже будут перестраиваться, что убивает производительность.


Как оптимизировать? Основные стратегии:

1. Кэширование и минимизация изменений

Сравнивайте новое значение со старым, чтобы избежать лишних присваиваний.

2. Использование TextMeshPro

TextMeshPro (TMP) имеет встроенный механизм кеширования текста и в целом более производителен при частом обновлении, чем стандартный Text. Но он всё равно вызывает перестройку при изменении текста.

3. Разделение Canvas

Один из самых действенных приёмов. Элементы, которые меняются часто (например, счётчик, health bar, полоса перезарядки), нужно помещать на отдельный, изолированный Canvas. Тогда при их обновлении будет перестраиваться меш только этого маленького Canvas, а не огромного основного интерфейса.

  • Статический Canvas: для фона, кнопок, статических надписей.
  • Динамический Canvas: для часто меняющихся элементов.

4. Оптимизация с помощью пула для динамических элементов

Если вы постоянно создаёте/уничтожаете UI-элементы (например, летящий урон), используйте объектный пул, чтобы избежать накладных расходов на инстанцирование и включение/выключение.

5. Отслеживание через Profiler

Всегда проверяйте UI-профиль в Unity Profiler:

  • Canvas.SendWillRenderCanvases — это главный метод, отвечающий за перестроение. Высокие значения времени его выполнения указывают на проблему.
  • Canvas.BuildBatch — процесс построения отрисовочного батча после перестройки меша.

Вывод: Перестройка меша Canvas — неизбежный механизм работы uGUI, но её частоту можно и нужно контролировать. Ключевые принципы: изменять свойства как можно реже, разделять статический и динамический контент по разным Canvas и всегда профилировать результат.