17 – Dev-консоль: SusConsoleService, SusConsoleDriver
Сервис:
SusConsoleService(sus-core/Runtime/Services/) Драйвер:SusConsoleDriver(sus-core/Runtime/Services/)
1. Назначение
Игровая dev-консоль: перехватывает логи Unity и показывает их поверх всего UI (категория Console = 50 — самый верх), позволяет фильтровать/искать и выполнять команды. Основной сценарий — отладка на устройстве/билде без Editor Console.

2. Подключение
Оберните в #if, чтобы исключить из release-сборок:
#if DEVELOPMENT_BUILD || UNITY_EDITOR
var overlay = SusBootstrap.GetOrCreateOverlay(uiDocument.rootVisualElement);
var console = new SusConsoleService
{
OverlayHost = overlay,
ToggleKey = KeyCode.BackQuote, // ~
MaxEntries = 500,
};
console.Attach(); // subscribes to the log, spawns the hotkey driver, sets Instance
#endifAttach() делает четыре вещи:
- Подписывается на
Application.logMessageReceivedThreaded. - Создаёт (или находит)
SusConsoleDriverдля опросаToggleKeyвUpdate. - Регистрирует встроенные команды (
clear,help,filter). - Публикует инстанс как
SusConsoleService.Instance(сеттер приватный — не присваивайте его вручную).
Detach() отписывается от лога и скрывает UI.
3. Использование
Интерфейс
Нажмите ~ — консоль открывается снизу (40% высоты экрана), тёмная панель:
| Элемент | Назначение |
|---|---|
| Кнопки All / Log / Warn / Err | Фильтр по типу |
| Поле поиска | Фильтр по подстроке (без учёта регистра) |
| Поле ввода команды | Введите команду → Enter → выполнение |
| Tab в поле команды | Автодополнение имени команды |
| ✕ | Закрыть консоль |
Цвета логов: серый (Log), жёлтый (Warning), красный (Error/Exception/Assert). Автопрокрутка вниз для новых сообщений; при ручной прокрутке вверх останавливается.
Стилизация
У консоли нет inline C#-стилей: весь overlay описан в Runtime/Resources/SusRuntime/sus-console.uss, который сервис загружает на собственный root при первом Show(). Цвета берутся из design-токенов (--sus-bg-overlay, --sus-primary, --sus-warning, --sus-error, …), поэтому консоль следует активной теме.
Чтобы изменить стиль, переопределите классы в любом sheet, загруженном после собственного sheet консоли (sheet проекта на панели, или через SusBootstrap.RegisterCascadeStyleSheet):
| Класс | Элемент |
|---|---|
.sus-console | Overlay-панель (position, height, background) |
.sus-console__toolbar | Верхняя строка |
.sus-console__filter / --active | Чипы фильтра All / Log / Warn / Err |
.sus-console__field + __search / __command | Текстовые поля ввода |
.sus-console__close | Кнопка ✕ |
.sus-console__list | ScrollView со строками лога |
.sus-console__line + --warning / --error | Строка лога |
.sus-console__status | Нижняя строка статуса (фильтр + число записей) |
Каждый var() в sheet несёт fallback, поэтому консоль выглядит корректно даже на голой панели, которая никогда не проходила через SusBootstrap и не имеет каскада токенов.
Регистрация команд
#if DEVELOPMENT_BUILD || UNITY_EDITOR
SusConsoleService.Instance.RegisterCommand("spawn", args =>
{
if (args.Length > 0)
SpawnUnit(args[0]);
else
Debug.Log("Usage: spawn <unitId>");
}, help: "Spawn a unit by id");
SusConsoleService.Instance.RegisterCommand("gold", args =>
{
int amount = args.Length > 0 ? int.Parse(args[0]) : 1000;
player.Gold += amount;
Debug.Log($"Added {amount} gold. Total: {player.Gold}");
}, help: "Add gold (default 1000)");
#endifВстроенные команды (регистрируются автоматически в Attach):
| Команда | Назначение |
|---|---|
clear | Очистить буфер лога |
help | Список всех команд |
filter <all|log|warn|error> | Переключить фильтр |
4. Архитектура
Потокобезопасность
Application.logMessageReceivedThreaded может вызываться из фонового потока. Записи добавляются в Queue<SusLogEntry> под lock. SusConsoleDriver.Update() вызывает DrainPendingEntries() в главном потоке — переносит записи в кольцевой буфер и обновляет UI.
Кольцевой буфер
При переполнении (MaxEntries, по умолчанию 500) старые записи вытесняются:
if (_buffer.Count >= MaxEntries)
_buffer.RemoveAt(0);
_buffer.Add(entry);Ленивое построение UI
UI (_root, _scrollView, toolbar, поле команды) строится при первом Show(). Когда консоль закрыта, она не создаёт VisualElement — нулевые накладные расходы на рендер.
Z-order
OverlayCategory.Console = 50 — верхний этаж screen-space OverlayHost. Консоль всегда выше modals, tooltips, dropdowns и toasts.
World-space UI (healthbars) не входит в этот стек: он использует отдельную панель под экранами. См. 07-overlayhost.md.
World-space panel ← UNDER screens (not OverlayHost)
└── healthbar / nameplate / …
Screen UIDocument
├── SusRouteView ← screens
└── OverlayHost
├── [Transition = 10]
├── [Modal = 20]
├── [Tooltip = 30] ← above modals
├── [Dropdown = 40]
├── [Toast = 45]
└── [Console = 50] ← console here (topmost)5. API
SusConsoleService
| Метод/свойство | Тип | Назначение |
|---|---|---|
Attach() | void | Подписка на лог + hotkey-драйвер |
Detach() | void | Отписка + закрытие |
Show() | void | Показать консоль |
Hide() | void | Скрыть |
Toggle() | void | Переключить |
Clear() | void | Очистить буфер |
DrainPendingEntries() | void | Перенос записей из очереди в буфер (главный поток) |
SetFilter(filter) | void | ConsoleFilter.All/Log/Warning/Error |
SetSearch(text) | void | Фильтр по подстроке |
RegisterCommand(name, handler, help) | void | Зарегистрировать команду |
ExecuteCommand(input) | bool | Выполнить строку команды |
IsOpen | bool | Открыта ли консоль? |
OverlayHost | OverlayHost | Контейнер портала |
ToggleKey | KeyCode | Хоткей (по умолчанию ~) |
MaxEntries | int | Размер кольцевого буфера (500) |
Instance | static SusConsoleService | Singleton |
SusConsoleDriver
public class SusConsoleDriver : MonoBehaviour
{
public SusConsoleService Service;
private void Update()
{
if (Input.GetKeyDown(Service.ToggleKey))
Service.Toggle();
Service.DrainPendingEntries();
}
}SusLogEntry
Строка кольцевого буфера оверлейной консоли (то, что SusConsoleService хранит после перехвата логов Unity). Не путать с процессным gated-логгером SusLog / SusLogLevel — см. 11-api-reference.
public struct SusLogEntry
{
public LogType Type; // Log, Warning, Error, Exception, Assert
public string Message; // Text
public string StackTrace; // Stack (for errors)
public float Time; // Time.unscaledTime
}ConsoleFilter
public enum ConsoleFilter { All, Log, Warning, Error }6. Тесты
| Файл | Тесты | Что покрывает |
|---|---|---|
sus-core/Runtime/Tests/SusConsoleServiceTests.cs | 10 playmode | Show/Hide/Toggle, перехват логов, переполнение буфера, фильтр, поиск, RegisterCommand/ExecuteCommand, Clear |