Решили: направление формы удара выводится из позы в момент касания — перпендикуляр к вектору «плечо → кончик оружия», знак разрешает вектор на цель. Пара точек «начало взмаха → попадание» изъята вместе с точкой A и её снимком.

Почему: хорда врала о направлении. Замер живого префаба (docs/lab/data/hit-geometry.json): кончик на StrikeStart лежит за спиной и выше (−0.71, +0.90), цель — впереди на два с лишним корпуса, поэтому хорда наклонена на ~20°, тогда как касательная в момент касания даёт ~75° вниз. Плюс длина знака бралась по длине хорды и выходила в полтора роста юнита. Отвергнуты: офлайн-замер клипа (нужен новый носитель данных и пересчёт при каждой перерисовке анимации) и история кадров (у быстрого замаха предыдущего кадра показа может не быть вовсе).

Сказано: «Он точно летит не от точки края меча в момент эвента начала замаха к точки хита» и «Нет, давай без легаси все же. Просто ругань, хихи» (06.08.2026, сессия a4e2eebd).

Грабли:

  • Точка A зависела от кадров показа, и это было незаметно. Снимок брался «на первом кадре, где скраб дошёл до StrikeStart», а скраб идёт по кадрам показа: у быстрой атаки таких кадров два-три, и точка уезжала к моменту контакта. Молча, без единого дефекта в консоли — путь через TryGetStrikeOrigin считал такой снимок валидным.
  • Рычаг мерится от ПЛЕЧА, а не от хвата. Вектор «хват → кончик» — это направление самого клинка, а не радиус вращения; перпендикуляр к нему дал бы поворот на 90° от истины при согнутой руке.
  • Знак касательной не хранится. Направление вращения могло бы приходить из клипа, но тогда его пришлось бы держать и обновлять; вектор на цель отвечает на тот же вопрос и переживает любую перерисовку анимации.
  • Удаление точки A потянуло чистку. Метод вида и поле снимка стали мёртвыми, но CaptureStrikeOrigin нельзя было убрать целиком: он же объявляет начало взмаха и заказывает дугу за клинком. Переименован в OpenSwing, проверки тела и оружия сохранены — без них дугу вести не на чем.
  • _LineWidth и _Softness — разные оси, и их легко перепутать. Мягкость живёт только на ВНУТРЕННИХ переходах между ступенями; внешняя граница обводки осталась резкой, иначе лайн перестаёт быть лайном.
  • Рванность дуги берёт сид из угла начала взмаха. Своего события у дуги нет, IRngService показу не принадлежит; угол постоянен всю жизнь эффекта (след не кипит покадрово) и разный у соседних ударов. Это подпорка, и она названа: понадобится честный сид — тянуть от сима.

Владелец правды: UnitView.TryGetStrikeDirection, HitFormParams (точка плюс направление), HitFormFactory (длина от урона), SH_Vfx_HitForm.shader / SH_Vfx_SwingArc.shader, CombatFeelConfig. Дизайн-сторона — канон gdd/70-gamefeel/vfx-language §«Серп лежит вдоль направления удара» и запись журнала ГД 2026-08-06/2.