Решили: у направления оружия остался ОДИН владелец — рисунок. Длина вылета по-прежнему
объявляется числом (UnitHeldItem.DeclaredLength), а куда смотрит рабочая часть, считается по мешу
(TryGetReachDirection); поле _declaredAxisDeg удалено. Отдельно: узлы предмета в руке больше не
анимируются — поворот перенесён в кисть во всех девяти клипах рига, и это держит тест
WeaponFollowsTheHandTests.
Почему: «куда смотрит меч» имело трёх владельцев сразу — поворот узла арта (24.9°), диагональ
самого рисунка внутри кадра (40.1°) и объявленную ось (32°). Первые два складываются в 65°, третий
жил своей жизнью, и дуга за клинком честно строила сектор к объявленному острию — то есть мимо меча
на треть прямого угла. Гейт DeclaredReachTests пропустил это, потому что сверял только ДЛИНУ: у
угла было два источника и ни одного арбитра, сверять было не с чем.
Длину и направление разделили намеренно, это разные факты. Длина — величина игровая: ей меряют размах и вылет, перерисовка арта не должна её двигать. Направление — факт чисто визуальный, и другого источника, кроме картинки, у него нет.
Перенос поворота в кисть — второй этаж той же ошибки: меч в руке жёсткая связь, и собственный поворот узла предмета означал второго владельца ориентации. Кривые складывались ключ-в-ключ вместе с тангенсами (производная суммы есть сумма производных), поэтому форма движения сохранена точно; там, где у кисти кривой не было, кривая оружия перенесена как есть — базовые повороты кистей в риге нулевые.
Сказано: «Я вижу, что надо поставить клинок в одно положение с рукой вдоль одной прямой и ЗАПРЕТИТЬ крутить оружие без руки. Согласна? И проверить что в анимациях такого нет» и раньше, про сам симптом: «Это вообще не след ЗА КЛИНКОМ… След должен идти за кромкой меча же, за самим мечом» (2026-08-07, сессия f0c50476). Кисть теперь поворачивается вместе с мечом — это принято Максом отдельным ответом: «Да, так и должно быть».
Грабли: симптом читался как дефект эффекта и трижды чинился в эффекте — сначала громкость затухания, потом единица длины хвоста, потом фиктивное время в стенде. Все три правки были нужны, но корень лежал двумя слоями ниже, в риге, и найден он был не рассуждением, а замером: угол вектора «хват → остриё» против угла нарисованного клинка. Числа стоило спросить раньше — они отвечали сразу.
Осталось незакрытым: рисунок клинка идёт по диагонали своего кадра (40°), поэтому «ноль на узле арта» до перерисовки недостижим. Это работа художника; код от неё уже не зависит — направление берётся оттуда, где клинок нарисован, каким бы он ни был.
Владелец правды: UnitHeldItem.TryGetReachDirection, тесты WeaponFollowsTheHandTests и
DeclaredReachTests.