Skip to main content
Как объясняется в документации по спрайтам, Visualizer Systems — это то, как клиентские спрайты изменяются с использованием данных внешнего вида (appearance data) с сервера. Старый метод заключается в использовании класса, наследующего AppearanceVisualizer, который указывается на AppearanceComponent. Новый способ — просто использовать компонент для данных, используемых для настройки визуализатора, и систему для фактической логики вместо одного класса. Преимущества в том, что они могут использовать всё, что могут ECS Systems (включая подписки на события, что важно!). Этот документ объясняет, как мигрировать AppearanceVisualizer на новый компонент и систему, используя базовый пример из этого PR: https://github.com/space-wizards-federation/space-station-14/pull/6571/files с некоторыми очень незначительными отклонениями. Директивы using и тому подобное не будут включены, так что вам нужно будет сделать их самостоятельно. Вот полный визуализатор, который мы переносим:

1. Разделите данные и логику

Первая задача — скопировать данные в новый компонент и скопировать логику в новую систему. Не беспокойтесь о полном переносе прямо сейчас или об ошибках, мы сделаем это позже. Компонент:
Система:

2. ECS-ификация данных

Теперь нам нужно преобразовать компонент в надлежащее состояние ECS!
  1. Сделать все приватные поля публичными
  2. Удалить любые свойства и использовать только поля напрямую; любая логика должна быть в методах-членах системы
  3. Изменить имена всех полей в соответствии с соглашениями об именовании
  4. Добавить дополнительные поля данных при необходимости
  5. Переместить соответствующий enum VisualLayers, если он существует, также в класс компонента
Теперь это будет выглядеть так:

3. ECS-ификация логики

Логику нужно перенести двумя способами:
  • Метод OnAppearanceChange необходимо преобразовать в соответствующее переопределение entity system
  • Любой метод InitializeEntity необходимо преобразовать в новый обработчик события ComponentInit, направленный на созданный вами компонент
Нужно сделать ещё кое-что:
  • Все зависимости должны быть перемещены в систему
  • Все ручные resolve должны быть преобразованы в зависимости
  • Все resolve IEntityManager должны использовать поле EntityManager, которое уже существует в EntitySystem, или прокси-методы
  • Все TryGet для SpriteComponent должны использовать поле Sprite в аргументах события
  • Все ссылки на поля, которые раньше были на визуализаторе, необходимо преобразовать в ссылки на поля компонента
Этот пример требует только первого, но я позже покажу пример второго. Сигнатура изменения внешнего вида теперь: protected override void OnAppearanceChange(EntityUid uid, T component, ref AppearanceChangeEvent args), поэтому мы обновим функцию соответствующим образом. Нам также нужно удалить resolve IEntityManager и преобразовать вызовы к нему в прокси-методы. Однако, поскольку используемые вызовы методов нужны только для получения SpriteComponent, мы можем использовать поле в аргументах события.
Этот пример не использует InitializeEntity, но если бы использовал, полный класс выглядел бы так:

4. Обновите YAML и IgnoredComponents.cs

Теперь нам нужно обновить YAML для нашего нового компонента, а также список игнорируемых сервером компонентов. Перейдите в Content.Server/Entry/IgnoredComponents.cs и добавьте строку с именем вашего нового компонента следующим образом:
Это делается автоматически для серверных компонентов, которых не существует на клиенте, но не наоборот, так как это обычно более редкая операция, и вы не можете сделать и то, и другое. Так что это просто говорит серверу не беспокоиться о том, что он видит этот компонент в YAML. Найдите использования старого визуализатора с помощью CTRL+SHIFT+F или эквивалента в любой IDE:
Замените это следующим образом:
Важно оставить компонент Appearance на месте! Легко пропустить баг. По сути, просто уменьшите отступ для блока visuals и измените имя компонента. Готово!

5. Если возможно, обобщите

Вместо добавления множества отдельных систем и компонентов визуализаторов часто можно сделать визуализатор более общим, добавив дополнительное YAML-поле данных. Для этого существует GenericVisualizerSystem и компонент, который заменяет старый GenericEnumVisualizer. Если всё, что вам нужно от визуализатора, — это установить некоторые данные слоя спрайта на основе простых записей данных внешнего вида, вы, скорее всего, можете и должны использовать generic visualizer вместо создания собственного. Однако если вам нужно делать что-то необычное, например, использовать анимации или более сложную логику, вам всё равно придётся создавать свой собственный. Например, функциональность вышеуказанного визуализатора шкафа просто устанавливает состояния и видимость слоя спрайта на основе двух записей данных внешнего вида. Вместо этой системы и компонента та же функциональность может быть достигнута с использованием generic visualizer:
Данные слоя спрайта могут устанавливать sprite, state, texture, shader, scale, rotation, offset, visible и color. Обратите внимание, что YAML для значений внешнего вида — это просто результаты ToString() значений данных внешнего вида. Таким образом, bool становятся “True”/“False”, а enum, такой как VentPumpState.Off, просто становится “Off”.
Последнее изменение 21 июня 2026 г.