Решили: шлейф за рывком и иллюзия уклонения строятся на ОДНОМ примитиве — призрачной копии тела
(GhostImage + пул CombatGhosts), а поза для неё снимается уже существующим UnitSilhouette, тем
же, которым рисуется drag-призрак расстановки. Признак «рывок свой, а не отброс» едет показу полем
снимка UnitSnapshot.IsSelfDisplaced.
Почему: оба эффекта — это «тело, оставшееся в прошлой точке», и разводить их по двум реализациям
значило бы дважды решать одни и те же две ловушки позы (зеркало отражённой команды и внутренний
порядок частей). Раскладка силуэта по рендерерам вынесена в общий SilhouetteDraw, потому что второй
её экземпляр разошёлся бы с первым молча: копия осталась бы нарисованной, просто неправильно.
Отвергнуто: клон иерархии костей (зависит от устройства рига, тянет Animator и скрипты) и снимок в RenderTexture (память и сортировка). Плоский набор рендереров с мировыми позами частей не знает про риг вообще.
Грабли: первым делом я пошла ловить маркер полёта (sys.airborne, тег KnockUp) через ленту как
EffectApplied — и это тупик: BattleTapeRecorder не пишет системные эффекты в ленту вовсе
(def.IsRuntime → выход), потому что показ по сети не смог бы разрешить их id. Признак полёта живёт
в снимке юнита, а не в событиях, и туда же пришлось положить его половину — «полёт начат самим»:
источник смещения дальше DisplacementSystem не уезжал, а по одной позиции показ намерение не
отличит. Чужой толчок ПЕРЕБИВАЕТ признак: по одному телу может идти несколько смещений сразу.
Второе: GhostImage — законное исключение из «все VFX — префабы», того же класса, что
DeathShatter. Копия повторяет конкретное тело в конкретной позе, префабом такое не подменить;
художественная часть при этом всё равно снаружи — материал берётся с самого тела, цвет с юнита, числа
жизни из CombatFeelConfig.
Владелец правды: GhostImage.cs, CombatGhosts.cs, SilhouetteDraw.cs,
CombatPresenter.UpdateGhostTrails, признак — RuntimeUnit.SelfDisplaced →
UnitSnapshot.IsSelfDisplaced → бит TapeChunkFormat.UnitFlag.SelfDisplaced; тумблер переписан в
FeelToggleCoverageTests.