Решили: порядок отрисовки двух скелетных юнитов рядом держится тремя уровнями, и вопрос «а если у частей свои ордера — Y ведь не поможет?» закрывается вторым из них, а не осью.

  1. Внутри юнитаSortingGroup на корне визуала (UnitView_BoneStandart, объект Visual Sprites, слой Units). Она делает ордера частей ЛОКАЛЬНЫМИ: 18 рендереров с ордерами −1..8 сравниваются только друг с другом.
  2. Между юнитами — ордер получает ГРУППА целиком: UnitView считает -round(renderPosition.y * 100) и отдаёт его через IUnitBodyVisual.SetSortingOrder. Один ордер на 0.01 мировой единицы Y.
  3. Ось CustomAxis (0,1,0) — только там, где ордер совпал; см. 2026-07-30-sprite-sorting-has-two-levels.

Почему именно так: без группы ордер части сравнивается с частями чужого юнита напрямую, и меч одного (ордер 2) уходит поверх торса другого (ордер 0) независимо от того, кто ближе к зрителю — ордер сильнее глубины, и ось этого не исправляет. Ровно это и есть проблема «разные части у двух юнитов». Альтернатива «писать Y-ордер в одну из частей» отвергнута и словами в коде, и по смыслу: часть уезжает по глобальной шкале, а остальное тело остаётся на локальной, и торс вырывается из собственного юнита. Схема совпадает с тем, что Unity описывает как канон для составных 2D-персонажей.

Грабли:

  • Группа стоит на префабе ВИДА, а не на риге. На BoneUnit_Standart её нет и быть не должно — он вкладывается внутрь вида. Первый взгляд на риг («группы нет!») даёт ложную тревогу; проверять надо UnitView_BoneStandart.
  • Слой сильнее ордера даже внутри группы. Часть, забытая в чужом sorting layer, всплывёт над всем телом, и выставленный ей ордер ничего не решит.
  • Предел ордера — int16. При точности 100 это |Y| ≈ 327 мировых единиц; для арены с запасом, но предел существует и при росте масштаба мира про него надо помнить.
  • Оружие не может пройти поверх чужого юнита — прямое следствие группы: юнит рисуется целиком либо спереди, либо сзади. Для боя «команда против команды» это норма (так же ведёт себя Gladiator Guild Manager). Если однажды понадобится замах поверх переднего юнита — решать отдельной группой или слоем для оружия на время удара, а не отключением группы.
  • Точное равенство Y (стартовая расстановка в один ряд) даёт совпавший ордер, и порядок между такими юнитами не определён. Практически они в этот момент и не перекрываются, а при движении Y расходится; страховка, если понадобится, — примешать к ордеру стабильный тай-брейк по id юнита.

Владелец правды: SpriteSortingSetupTests (группа есть, части в одном слое), UnitView.cs (формула ордера по Y), SkeletalBodyVisual (внутренний порядок частей).