Решили: размер боевого VFX имеет ровно одного владельца — VfxData.SizeUnits, размер крупнейшей
частицы в мировых единицах. Префаб задаёт пропорции частиц между собой, PooledVfx приводит их к
абсолюту через масштаб трансформа, а единственный рантайм-множитель переименован из «интенсивности» в
EvaluateHitVfxSizeMultiplier и живёт в feel-конфиге. Инвариантов четыре, все в
VfxSizeContractTests: кривая sizeOverLifetime обязана где-то достигать 1.0; корневой localScale
префаба равен единице; scalingMode не Local; бёрст гарантирует хотя бы одну частицу. Пятый тест
печатает реестр размеров в пикселях боевого кадра — то, чего не было видно ни из префаба, ни из SO.
Почему: у размера было четыре владельца — startSize префаба, скрытая кривая, множитель в SO и
множитель силы удара. Каждый по отдельности выглядел осмысленно, а произведение давало искру в два
пикселя при заявленных в инспекторе 0.09. Отвергнута «общая VfxFactory»: CombatVfx уже фабрика
(пул, спавн, применение SO), и второй слой поверх не убрал бы ни одного множителя — течёт не спавн, а
число. Порог _vfxHitSizeMultMin поднят с 0.35 до 0.7: втрое урезанный размер снова уводил эффект в
невидимость, и Range у поля начинается с 0.3, чтобы 0.35 нельзя было вернуть случайно.
Грабли:
burst.count.constantMinпри режимеConstantвсегда ноль — это неиспользуемое поле, а не «бёрст может выдать нуль частиц». Все наши бёрсты именноConstant, то есть количество фиксированное. Из-за этого запись вconstantMinмолча ничего не делает: правка «поднять минимумы» в коммитеae8ebd2caбыла пустой, а вывод предыдущей записи журнала про «удар иногда без искр» — неверен. Гарантированный минимум читается по режиму:Constant→constant,TwoConstants→constantMin.- Кривая
Vfx_CastBurst/Coreрастёт (расширяющееся ядро) и упиралась в пик 0.90 — заявленныйstartSizeбыл недостижим и там. Нормирована в0.389 → 1.00: форма роста та же, пик честный, аSizeUnitsуменьшен на те же 10% (0.77 → 0.69), чтобы вид не изменился. compile-check.ps1без-Allдаёт ложную ошибку, если редактор давно не компилировал: он ссылается на DLL изLibrary, и зависимая сборка не видит свойства, добавленного в другую сборку свежим коммитом. Здесь это выглядело какUnitSnapshot не содержит IsSwingingпри том, что свойство в коде есть.-Allсобирает своими выходами и проходит.- Сканирование
AnimationCurveдробным аккумулятором (for t += 0.05f) не доходит доt = 1, где у растущей кривой стоит пик. Шагать целыми.
Владелец правды: VfxData.SizeUnits (абсолют), PooledVfx.ResolveTransformScale (приведение
пропорций), CombatFeelConfig.EvaluateHitVfxSizeMultiplier (единственная динамика),
тест VfxSizeContractTests (все четыре инварианта и реестр в пикселях).