Единый источник цвета боевых эффектов — юнит, а не префаб эффекта. Здесь: где живут поля, кто их читает, какие числа считаются нормой и три готчи, каждая из которых стоила захода.

Дизайн-правило (почему именно так) — Vision - VFX Color. Слой презентации — слой презентации (код Assets/_Project/Scripts/Presentation/).

Правило номер один: насыщенность 70–90%, ни один канал не в нуле, яркость выше порога bloom. Не «максимально ярко и насыщенно» — эти два требования конфликтуют в одном пикселе.


1. Поля

Цветов на UnitData больше нет ни одного (с 30.07.2026) — только роли:

ПолеТипСмысл
_vfxToneUnitToneоттенок свечения: чем юнит светит
_bodyShadeBodyShadeступень приглушения тела; None = арт как нарисован

Значение по роли отдаёт палитра проекта (UI/Theme/tokens.*.ussGuildmasterPalette):

  • UnitColorRoles.Tone/Shade — LDR-цвет роли; единственное место, где имя USS-токена связано с элементом перечисления (сторож — UnitTintPolicyTests.EveryRole_ExistsInThePalette).
  • CombatColorPalette.UnitMain/UnitSpread — тот же цвет, поднятый в HDR множителями (см. §4). Градиент разброса кэшируется по РОЛИ: Gradient — класс, собирать его на каждом ударе значило бы мусорить в бою, а от юнита он уже не зависит.
  • CombatColorPalette.BodyTint — цвет ступени приглушения; его же путём красит карточку инвентаря.

2. Потребители

Что краситсяЧемТочка в коде
Тело снарядаглавный цветCombatPresenter.cs:240ProjectileView.Bind
След снаряда (trail)главный цвет, к хвосту падает альфаProjectileView.ApplyTrail
Контур кастаглавный цветCombatPresenter.cs:288UnitView.PlayCastOutline
Дульная вспышкапалитраCombatPresenter.cs:233
Всплеск каста за манупалитраCombatPresenter.cs:291
Искры ударапалитра бьющегоCombatPresenter.cs:402
Вспышка леченияпалитра лечащегоCombatPresenter.cs:433
Осколки смертипалитра павшего + около-белый из CombatFeelConfigUnitView.cs:1249DeathShatter.Play

Не красится цветом юнита: пыль под ногами, дым, земля — они принадлежат миру.

3. Готчи

Палитра читается ТОЛЬКО по концам. И частицы (PooledVfx.ApplyTint), и шейдер осколков (DeathShatter_ShardUnitA/_ShardUnitB) берут Evaluate(0) и Evaluate(1) и отдают их как границы ParticleSystem.MinMaxGradient. Промежуточные ключи не влияют ни на что. Поэтому конец 0 — пересвет, конец 1 — насыщенный цвет; «красивый градиент из четырёх ключей» работать не будет.

Порог bloom — 1.0 (Assets/DefaultVolumeProfile.asset, intensity 1, scatter 0.55). Цвет, выведенный ровно в 1.0, не светится вообще. Поэтому в палитре живёт LDR-база, а всё, что должно сверкать, поднимается множителями (§4): HDR в снимок палитры не едет — значение больше единицы это уже не оттенок, а сила свечения.

Роль без токена — пурпур и ошибка в консоль. Добавили элемент в UnitTone, но не завели роль в tokens.semantic.uss или не пересобрали снимок — юнит светит пурпуром. Тихо подставить «похожий» цвет нельзя: цвет юнита несёт, кто именно бьёт.

4. Множители авторинга

База в палитре — HSV с насыщенностью 70–90% и яркостью 1. Дальше её поднимает CombatColorPalette (поля ассета, не константы кода):

ЧтоМножительПример (огонь, база 1, 0.47, 0.2)
Главный цвет×2.02.0, 0.93, 0.4
Палитра, конец 1 (насыщенный)×2.22.2, 1.03, 0.44
Палитра, конец 0 (пересвет)смесь с белым 75%, затем ×2.62.6, 2.26, 2.08

Пересвет — это тот же оттенок, потерявший насыщенность, а не абстрактный белый: тёплый юнит пересвечивает тёпло-белым, холодный — холодно-белым. Альфа множителями НЕ трогается: её занимает прозрачность тела (стелс).

5. Кому какая роль — не здесь

Назначение ролей по ростеру — дизайн-решение, и владелец у него один: Vision - VFX Color §Ростер. Здесь до 30.07.2026 лежала таблица баз RGB и была вторым владельцем того же факта.

Приглушение тела (_bodyShade) от оттенка независимо: оно про то, как юнит ВЫГЛЯДИТ, роль оттенка — про то, чем он СВЕТИТ. Ступень ставится только тем, кто делит спрайт с другим юнитом (сторож — UnitTintPolicyTests), поэтому у большинства она None.


Связано: Vision - VFX Color, слой презентации (код Assets/_Project/Scripts/Presentation/), дата-слой (код Assets/_Project/Scripts/Data/, правила — скилл xgaida-x-nixi-data-authoring).