Решили: масштабный инвариант сборки юнита — 1 пиксель фигуры (1x) = 0.01 мировой единицы,
подошва фигуры на y = 0, ось симметрии на x = 0. Отсюда человек тира 128 занимает ровно
1.27 юнита, и это проверяется габаритом собранного префаба, а не верой.
Почему именно 0.01: арт экспортируется в ×10 (export_bone_parts.lua, канон ради вращения без
мыла), а spritePixelsToUnits у частей 1000 — 10/1000 и даёт сотую. Число не выбиралось заново:
обе половины уже стояли, надо было только их перемножить и записать, чтобы позиции частей считались,
а не подгонялись глазом.
Инвариант живёт между тремя местами и потому опасен: масштаб экспорта в lua, PPU в пресете
импорта BonePartSprite.preset, координаты в генераторе раскладки. Сменить одно, забыв два других,
означает фигуру верной формы и неверного размера — самая тихая из возможных поломок. Генератор
раскладки держит формулу в шапке и считает всё от неё.
Грабли:
Newtonsoft.Jsonвexecute_codeне собирается:JObjectиJArrayсуществуют одновременно вNewtonsoft.Jsonи вUnity.Localization.ThirdParty.Editor, компилятор жалуется на неоднозначность, а alias в теле метода не объявить. Обход — не тащить JSON внутрь Unity вовсе: раскладка передаётся построчным текстом с разделителем|, который парситсяstring.Split.Objectвexecute_codeтоже неоднозначен (UnityEngine.Objectпротивobject) — писать полным именем.- Данные для сборки генерируются скриптом из
.aseprite, а не набираются руками: девятнадцать узлов и восемнадцать позиций с точностью до сотой не набираются без ошибок.
Владелец правды: Assets/_Project/Prefabs/Bones/BoneUnit_Human128.prefab (собранный риг),
Aseprite/scripts/export_bone_parts.lua (масштаб ×10),
Assets/_Project/Art/Sprites/Bone Animations/BonePartSprite.preset (PPU 1000),
docs/unit-128-rig-progress.md (живой заход, временный).