В UI Toolkit у каждого `VisualElement` есть собственный «планировщик» (scheduler). Доступ к нему даёт свойство **`schedule`**, а цепочка **`Execute(() => { … })`** добавляет задачу (callback), которую планировщик выполнит на ближайшем обновлении панели UI. ([docs.unity3d.com](https://docs.unity3d.com/6000.1/Documentation/ScriptReference/UIElements.VisualElement-schedule.html?utm_source=chatgpt.com "UIElements.VisualElement.schedule - Scripting API - Unity - Manual"), [docs.unity3d.com](https://docs.unity3d.com/ScriptReference/UIElements.IVisualElementScheduler.html?utm_source=chatgpt.com "IVisualElementScheduler - Scripting API - Unity - Manual")) --- ### Зачем это нужно - **Одноразовый вызов** — замена `EditorApplication.delayCall` или `Invoke` для UI: код выполнится один раз в самом конце текущего кадра, когда все стили уже рассчитаны. - **Периодические операции** — можно продолжить цепочку `.Every(ms)` для таймеров/анимаций без `Coroutine` и без `Update()`-циклов. - **Жизненный цикл UI** — задача автоматически **приостанавливается**, если элемент убрали из иерархии, и **возобновляется**, когда вернули. Это защищает от утечек (memory leak) и лишних вызовов. - **Изменение частоты / остановка** — у возвращаемого `IVisualElementScheduledItem` есть методы `Pause()`, `Resume()`, `Until(predicate)`, `StartingIn(ms)` для тонкой настройки. --- ### Мини-пример ```csharp // Обновляем счётчик FPS в редакторском окне каждую секунду Label fpsLabel = new Label(); root.Add(fpsLabel); // Планируем задачу fpsLabel.schedule .Execute(() => // первый вызов – на следующем кадре { float fps = 1f / Time.smoothDeltaTime; fpsLabel.text = quot;FPS: {fps:F1}"; }) .Every(1000); // затем – каждые 1000 мс ``` > **Производительность (performance)**: сам планировщик объединяет все задачи панели в один список; накладные расходы минимальны (~O(1) на добавление/удаление, O(n) на кадр, где _n_ – число активных задач). Тем не менее не перегружайте callback тяжёлыми вычислениями – перемещайте логику в фоновые потоки или ECS-системы, а в UI лишь отображайте результат. --- ### Полезные цепочки |Что нужно|Как записать|Пояснение| |---|---|---| |Отложить на 200 мс|`.StartingIn(200)`|Выполнится один раз через 0,2 с| |Выполнять каждые 16 мс|`.Every(16)`|~60 кадров/с для простых анимаций| |Остановить при условии|`.Until(() => finished)`|Автоматически снимает задачу| |Поставить «паузу»|`item.Pause()` / `Resume()`|Можно временно отключить без GC| --- ### Итоги `_editor.schedule.Execute(() => …)` — это удобный, малозатратный способ выполнять одноразовые или периодические действия, «привязанные» к жизненному циклу самого UI-элемента, без необходимости писать собственные `Coroutine` или перехватывать `Update()`.