Перейти к содержимому
CRUSHFORMV1.1.0
ПОЛУЧИТЬ НА FAB

ПОВЕРХНОСТИДЕФОРМАЦИЯ ШИН

Деформация шин

Шина под нагрузкой не остаётся круглой. Там, где она касается земли, она выпячивается по бокам и проседает в пятне контакта, а чем сильнее машина давит на неё, тем больше шина сплющивается. Плагин рисует это на мешах колёс автомобиля, поэтому шина выглядит нагруженной на любом грунте. Шина, прижатая к круглому препятствию, например к брусу, бревну или скруглённому краю бордюра, обволакивает его, а колесо отходит от препятствия, чтобы обод оставался снаружи. На этой странице описаны профиль, который это задаёт, бюджет, который решает, какие шины так деформируются, и как настроить и то и другое.

Вид сбоку снизу на заднюю шину седана на дороге: по бокам она выпячивается, а там, где касается земли, сплющена.
Задняя шина седана: по бокам она выпячивается, а в месте контакта сплющивается.

Каждое колесо автомобиля получает деформатор шины, пока бюджет его выделяет. Деформатор трассирует грунт под шиной и записывает контакт в меш колеса, а материал шины рисует выпячивание по этим контактам. Шина, которой бюджет не выделил деформатор, не получает выпячивания. Шины вашего собственного автомобиля деформируются всегда, а шины других автомобилей деформируются, пока они находятся рядом с камерой и в пределах лимита бюджета.

  • Контакты. Шина трассирует грунт веером лучей. Num Arc Samples лучей пересекают дугу контакта, а Num Lateral Rows рядов пересекают протектор. Каждый контакт записывается в Custom Primitive Data меша колеса, 32 float, которые читает MF_CF_TireDeform. M_CF_TireDeform — материал шины, который это использует.
  • Глубина. Max Deflection ограничивает самую глубокую вмятину в сантиметрах. Вмятина растёт и сходит со временем, со скоростями Depth Grow Speed и Depth Fade Speed.
  • Препятствия. Там, где веер попадает в круглое препятствие, шина читает его кривизну в плоскости колеса по трём соседним попаданиям, а материал шины вдавливает её в эту окружность со скруглённым краем. Окружность принимается, только если нормали трёх попаданий с ней согласны, поэтому ровный грунт и острый угол бордюра сохраняют плоское вдавливание. Препятствие тоньше Min Obstacle Radius вдавливается так, будто оно такой толщины. Близкие попадания сливаются в один контакт, только если их нормали отличаются не больше чем на Merge Angle Deg; низкое значение даёт маленькому круглому препятствию под большой шиной занять все четыре контакта, и земля теряет свой.
  • Выталкивание. Шина вминается, пока между препятствием и ободом не остаётся только Rubber Margin резины. Глубже она просит host-объект отодвинуть всё колесо от препятствия, не дальше чем на Max Push, и вминается на остаток. Выталкивание уходит host-объекту как FCFTireWheelOffset::PushCm, если он его принимает (FCFTireWheelDesc::bAcceptsPush). Оба адаптера принимают. Blueprint, который переопределяет Set Crushform Tire Wheel Offsets, расставляет колёса сам: выталкивание тогда не вычисляется, шина вминается так же, как без него, до Max Deflection, и обод может войти в препятствие. Радиус обода берётся из параметра RimRadius материала шины или из Rim Radius Override в профиле. Колесо без того и другого не выталкивается никогда.
  • Нагрузка. Автомобиль сообщает силу контакта каждой шины относительно её номинальной нагрузки. Коэффициент нагрузки шины смещается к 1 + Load Sensitivity * (ratio - 1), удерживаясь между 0 и Max Load Factor. Сильно нагруженный поворот сжимает шину сильнее. Стоящая шина сжимается на Resting Deflection, долю её радиуса.
  • Бюджет. Настройка Scope определяет, какие шины деформируются. RigOnly позволяет деформироваться только шинам автомобиля зрителя. Budgeted, значение по умолчанию, добавляет шины других автомобилей в пределах радиуса: сначала видимые, сначала ближайшие, до Max Wheels колёс. Unlimited даёт каждой шине полную детализацию без бюджета. Сцепка зрителя, то есть его автомобиль и всё, что к нему сцеплено, деформируется всегда, даже сверх лимита. Пешка сообщает через ICFTireViewer, в каком автомобиле она едет. Значения бюджета — настройки проекта, и у каждой есть переменная консоли, которая её переопределяет; см. Настройки проекта и Производительность.
  • Детализация. Шина дальше Lod Distance 1 трассирует более редкий веер, а дальше Lod Distance 2 — самый редкий веер против простой коллизии.
  • Сон. Колесо, которое успокоилось и остаётся в пределах Sleep Distance и Sleep Angle Deg от положения покоя, может заснуть: оно перестаёт трассировать, пока его поза не изменится. Отрицательное Sleep Distance не даёт колесу уснуть никогда.
  • Выделенный сервер. Выделенный сервер шины не рисует, поэтому компонент шин там простаивает.
  1. В Content Browser выберите Add > Miscellaneous > Data Asset, укажите класс CFTire Profile и назовите ассет DA_MyVehicle_TireProfile. Значения по умолчанию — хорошее начало: 13 отсчётов дуги, 3 ряда по протектору и максимальный прогиб 14 см.
  2. На компоненте адаптера автомобиля задайте Tire Profile равным новому профилю и поставьте галочку Tires. Если Tire Profile пуст, используется профиль шин проекта по умолчанию, /Crushform/Presets/DA_CF_DefaultTireProfile.
  3. Дайте мешам шин материал, который использует MF_CF_TireDeform. Проще всего начать с копии M_CF_TireDeform со своими цветами. Задайте её параметру RimRadius радиус обода в единицах меша, чтобы колесо можно было вытолкнуть от препятствия, прежде чем обод в него войдёт. Или задайте в профиле Rim Radius Override в сантиметрах.
  4. В Project Settings > Plugins > Crushform Tire проверьте Scope в разделе Budget. По умолчанию это Budgeted. Объектные каналы, которые трассировка шины должна игнорировать, добавьте в Tracing. Остальные значения Budget и пороги Sleep тоже здесь; см. Настройки проекта.

Blueprint обращается к компоненту шин через геттер адаптера Get Tires. У компонента нет собственных функций Blueprint, поэтому график ниже работает через геттер. Когда срабатывает пользовательское событие CheckTyres, график проверяет, что у автомобиля есть компонент шин, и выводит результат. Это быстрая проверка перед тем, как скрипт настройки коснётся шин. Работа с самими шинами в Blueprint идёт через собственные события адаптера: Build Tire Wheels перечисляет колёса, а Build Load Ratios даёт нагрузку каждого колеса.

Когда срабатывает пользовательское событие CheckTyres, график проверяет, что у автомобиля есть компонент шин, и выводит результат.

Из C++ задайте профиль компонента шин. Для вызовов нужны модуль CrushformVehicle (адаптер, CFVehicleAdapterComponent.h) и модуль CrushformTire (CFTireComponent.h), которые добавьте в PublicDependencyModuleNames в Build.cs вашего модуля. Профиль, заданный после начала игры, также подключает компонент к бюджету.

UCFTireComponent* Tires = Adapter->GetTires();
Tires->SetProfile(MyTireProfile);

Пешка, которая может сесть в автомобиль, реализует ICFTireViewer из CFTireViewer.h модуля CrushformTire и возвращает автомобиль, в котором едет, чтобы бюджет оставлял деформированными шины этого автомобиля.

AActor* GetCrushformTireViewedHost_Implementation() const override;
СвойствоЧто делаетПо умолчанию
UCFTireProfile::TraceChannelКанал, по которому шина трассирует грунт.ECC_WorldStatic
UCFTireProfile::NumArcSamplesЛучи по дуге контакта.13
UCFTireProfile::NumLateralRowsРяды лучей по протектору.3
UCFTireProfile::MaxDeflectionСамая глубокая вмятина в сантиметрах.14
UCFTireProfile::RestingDeflectionНа сколько сжата стоящая шина, как доля её радиуса.0.05
UCFTireProfile::LoadSensitivityНасколько нагрузка меняет сжатие.1
UCFTireProfile::MaxLoadFactorНаибольшее значение коэффициента нагрузки.2.5
UCFTireProfile::MergeAngleDegБлизкие контакты сливаются в один, только если их нормали отличаются не больше чем на это значение, в градусах. Низкое значение даёт маленькому круглому препятствию под большой шиной занять все четыре контакта, и земля теряет свой.45
UCFTireProfile::MinObstacleRadiusНаименьший радиус, см, до которого читается кривизна круглого препятствия. Более тонкое препятствие, например труба, прогибает шину так, будто оно такой толщины.3
UCFTireProfile::RimRadiusOverrideРадиус обода, см. 0 читает параметр RimRadius материала шины.0
UCFTireProfile::RubberMarginРезина, которая остаётся между препятствием и ободом, см, когда колесо сдвинуто с препятствия.2
UCFTireProfile::MaxPushНаибольший сдвиг всего колеса с препятствия, см. За этим пределом обод может войти в препятствие.10
UCFTireSettings::ScopeКакие шины деформируются: только сцепка зрителя, сцепка и бюджет или каждая шина.Budgeted
UCFTireSettings::IgnoredObjectChannelsОбъектные каналы, которые трассировка грунта игнорирует, помимо собственного канала шины.Пусто
UCFTireSettings::DefaultProfileПрофиль шины, которая свой не указывает./Crushform/Presets/DA_CF_DefaultTireProfile
UCFSettings::TireCustomDataOffsetПервый индекс Custom Primitive Data для контактов шин.0
UCFTireSettings::bEnabledВключено: шины деформируются; выключено: каждая шина возвращается к круглой форме. Переопределяется переменной консоли Crushform.Tire.Enable.Включено
UCFTireSettings::MaxWheelsСколько шин могут деформироваться одновременно. Переопределяется переменной консоли Crushform.Tire.MaxWheels.30
UCFTireSettings::RadiusРасстояние от камеры в сантиметрах, в пределах которого могут деформироваться другие шины. Переопределяется переменной консоли Crushform.Tire.Radius.4000
UCFTireSettings::LodDistance1Расстояние от камеры в сантиметрах, дальше которого шина трассирует более редкий веер лучей. Переопределяется переменной консоли Crushform.Tire.LodDistance1.1500
UCFTireSettings::LodDistance2Расстояние от камеры в сантиметрах, дальше которого шина трассирует самый редкий веер против простой коллизии. Переопределяется переменной консоли Crushform.Tire.LodDistance2.3000
UCFTireSettings::HysteresisНа сколько расширяются границы выделенной шины, чтобы шина на границе не мерцала. Читается в пределах от 0 до 0.9. Переопределяется переменной консоли Crushform.Tire.Hysteresis.0.15
UCFTireSettings::UpdateIntervalСекунды между двумя проходами бюджета. Переопределяется переменной консоли Crushform.Tire.UpdateInterval.0.25
UCFTireSettings::OnScreenToleranceСекунды после последней отрисовки колеса, в течение которых оно ещё считается видимым. Переопределяется переменной консоли Crushform.Tire.OnScreenTolerance.0.5
UCFTireSettings::SleepDistanceРасстояние от положения покоя в сантиметрах, в пределах которого шина может уснуть. Отрицательное значение не даёт ей уснуть никогда.1
UCFTireSettings::SleepAngleDegУгол от положения покоя в градусах, в пределах которого шина может уснуть.0.5

Откройте консоль и выполните Crushform.Tire.Debug 2. Уровень 1 выводит на экран число шин. Уровень 2 также рисует для каждой шины подпись с её уровнем детализации и состоянием выделения, например T0 granted (уровень 0 — самый точный), зелёную точку в ступице (синюю, пока шина спит) и в каждом контакте с землёй красную точку с жёлтой линией вдоль нормали контакта. Затем запустите Lvl_ProvingGround, проведите седан по неровностям и спрыгните с трамплина. Шины выпячиваются там, где касаются земли, и пока это происходит, подписи и точки видны на шинах. Строка Tyres в панели отладки показывает Off, Counts или Rays и делает то же самое. Всё это доступно в любой сборке, кроме Shipping. Чтобы увидеть обволакивание, прижмите шину к круглому препятствию на своём уровне, например к брусу или бревну: протектор обволакивает его, а колесо отходит от препятствия, и обод остаётся снаружи.

Задние колёса седана с включённой отладочной отрисовкой шин: зелёная подпись на каждой шине с текстом T0 granted, зелёные точки в ступицах и красные точки контакта с жёлтыми линиями на земле.
Crushform.Tire.Debug 2: уровень детализации и состояние выделения каждой шины, её ступица и её контакты с землёй.
Седан спереди: его шины сплющиваются под собственным весом.

Причина. Компонент шины без профиля ничего не делает. Шины автомобиля остаются круглыми, и лог говорит об этом только на уровне Verbose. Enabled в Crushform Tire, выключенный, или Crushform.Tire.Enable 0 из консоли возвращает каждую шину к круглой форме. Host-объект, который не реализует ICFTireHost, даёт тот же результат и пишет предупреждение:

%s: the host %s does not implement ICFTireHost, its tyres stay round

Решение. Задайте Tire Profile на адаптере или Default Profile в Crushform Tire и включите Enabled в Crushform Tire (консольная Crushform.Tire.Enable 0 по-прежнему переопределяет его на время сессии). Проверьте, что автомобиль является host-объектом: адаптер им является, а пользовательский эктор должен реализовать ICFTireHost.

Причина. Budgeted выделяет шину только внутри Radius и только до Max Wheels шин всего. Ваш собственный автомобиль выделяется всегда, а остальные автомобили делят то, что осталось.

Решение. Увеличьте Radius или Max Wheels в Project Settings › Plugins › Crushform Tire (Crushform.Tire.Radius и Crushform.Tire.MaxWheels переопределяют их на время сессии) либо задайте Scope равным Unlimited, чтобы дать каждой шине полную детализацию. Проверьте бюджет командой Crushform.Tire.Debug 1.

Причина. Колесо не выталкивается от препятствия. Так бывает, когда у колеса нет радиуса обода, потому что не задан ни RimRadius материала шины, ни Rim Radius Override в профиле; когда его host-объект не принимает выталкивание, как у Blueprint, который переопределяет Set Crushform Tire Wheel Offsets; или когда препятствие глубже, чем позволяет Max Push.

Решение. Задайте RimRadius на материале шины или Rim Radius Override в профиле. На собственном host-объекте применяйте PushCm в SetCrushformTireWheelOffsets и ставьте bAcceptsPush; см. Host-интерфейсы. Увеличьте Max Push, если препятствие глубже, чем колесо можно вытолкнуть.

Шины не деформируются на выделенном сервере

Заголовок раздела «Шины не деформируются на выделенном сервере»

Причина. Выделенный сервер шины не рисует. Компонент простаивает и пишет об этом на уровне Verbose.

Решение. Проверяйте шины на клиенте или на слушающем сервере.

Причина. Блок шин занимает 32 float, начиная с Tire Custom Data Offset, который принимает значения от 0 до 4. Блок должен заканчиваться до блока загрязнения колеса, который начинается с Wheel Custom Data Offset и по умолчанию равен 34. При значении больше 2 блок заходит в этот блок загрязнения, и лог говорит об этом один раз:

%s: TireCustomDataOffset %d does not fit the primitive clear of WheelCustomDataOffset %d, tyre contacts are not written

Решение. Верните Tire Custom Data Offset к 0, значению по умолчанию, которое использует индексы от 0 до 31. Редактор пересобирает зависящие от него функции материала, когда значение меняется.