Решили: порядок отрисовки двух скелетных юнитов рядом держится тремя уровнями, и вопрос «а если у частей свои ордера — Y ведь не поможет?» закрывается вторым из них, а не осью.
- Внутри юнита —
SortingGroupна корне визуала (UnitView_BoneStandart, объектVisual Sprites, слойUnits). Она делает ордера частей ЛОКАЛЬНЫМИ: 18 рендереров с ордерами −1..8 сравниваются только друг с другом. - Между юнитами — ордер получает ГРУППА целиком:
UnitViewсчитает-round(renderPosition.y * 100)и отдаёт его черезIUnitBodyVisual.SetSortingOrder. Один ордер на 0.01 мировой единицы Y. - Ось
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 (внутренний порядок частей).