МИРОТКЛИК НА УДАРЫ
Отклик на удары
Что это делает
Заголовок раздела «Что это делает»Когда автомобиль врезается в стену, забор, дерево или окно, он издаёт звук и выбрасывает искры. Когда разрушаемый фрагмент приземляется, он издаёт глухой стук. Отклик на удары — та часть Crushform, которая всё это проигрывает. Она превращает удар в событие удара, находит, как это событие должно звучать и выглядеть, и проигрывает его в месте удара.
Если включена консольная переменная LogHits, плагин сообщает о каждом ударе, который он оценивает. В сеансе игры в редакторе каждый удар оставляет маркер на 5 секунд: сферу в точке удара со стрелкой вдоль нормали поверхности. Маркер зелёный, когда удар проигрывается, жёлтый — для удара внутри устойчивого контакта, и красный — для удара ниже минимума. Каждый оценённый удар также пишет одну строку в лог, в категорию LogCrushformImpact, в таком виде:
<owner>: <component> (bone <bone>) hit by <actor> / <component>, impulse N, support N, mass N kg, other mass N kg, normal Z N, intensity N at <point>: <verdict>Вердикт — played, below minimum или steady contact, suppressed.
Как это работает
Заголовок раздела «Как это работает»Каждый удар — это gameplay-тег, например Crushform.Impact.Prop.Break.Wood, который проигрывается в точке. Остальное делает UCFImpactFeedbackSubsystem:
- Он находит строку для тега в активном наборе ударов. Если в наборе нет строки для этого точного тега, используется строка ближайшего родительского тега, у которого она есть. Если ни одна строка не подходит, ничего не проигрывается.
- Он проигрывает один звук из строки, выбранный случайно, и порождает эффект Niagara строки с заданным параметром
Intensity. - Он масштабирует громкость между значениями Volume by Intensity строки и выбирает высоту тона из её Pitch Range.
- Он применяет фильтры строки: удар ниже Min Intensity ничего не проигрывает, источник, который недавно проигрывал звук, ждёт свой Cooldown Seconds, а пока заняты Max Concurrent Voices строки, новый удар проигрывает эффект, но без звука. На весь плагин в одном кадре стартует не больше Max Sounds Per Frame звуков (по умолчанию 2): остальные ждут следующих кадров, самые сильные первыми, а звук, который всё ещё ждёт после Sound Queue Seconds (0.15 с), отбрасывается. Если запустить в одном кадре звуки аварии, которая даёт их сразу много, получится рывок, поэтому их растягивают на несколько кадров. Эффекты в очередь не ставятся.
Набор ударов — ассет данных UCFImpactFeedbackSet. Набор проекта по умолчанию — /Crushform/Impact/DA_CF_ImpactFeedback, со строкой для каждого тега плагина. Проект может создать свой набор и указать его в Default Set.
Удары исходят от компонентов, которые сидят на теле. Вы добавляете их в меню Add редактора Blueprint, где все три перечислены в разделе Custom, а не в Crushform:
UCFImpactFeedbackComponentсообщает об ударах наблюдаемого примитива с Event Tag, который ему задан (по умолчаниюCrushform.Impact.Hit). Он ничего не наблюдает, пока вы не передадите ему примитив черезSetObservedPrimitive, это только C++. Удар оценивается по импульсу на килограмм тела. Ниже Min Impulse Per Kg (50) он молчит, а в полную силу звучит при Impulse Per Kg for Full Intensity (600). Устойчивый контакт, например тело, опирающееся на землю, не повторяет удар.UCFNetImpactFeedbackComponentсам наблюдает корневой примитив своего владельца и также передаёт удар другим игрокам. Передача обычно ждёт не меньше Min Relay Interval Seconds (0,5 с) и приходит раньше для заметно более сильного удара.UCFPartImpactFeedbackComponentпроигрывает удар навесной детали, когда она достигает конца своего хода. Деталь, которая ударяется о закрытый конец, проигрывает Slam Event Tag, по умолчаниюCrushform.Impact.Part.Slam. Деталь, отброшенная далеко в открытый конец, проигрывает Open Slam Event Tag, по умолчаниюCrushform.Impact.Part.Slam.Open, а набор ударов без строки для этого тега проигрывает строкуPart.Slam.
Автомобиль получает эти компоненты от своего адаптера. Определение разрушаемого объекта называет свои теги, а пустой тег проигрывает тег плагина по умолчанию.
Плагин объявляет 19 тегов ударов в CFImpactTags:
| Тег | Проигрывается, когда |
|---|---|
Crushform.Impact | Корень событий ударов. |
Crushform.Impact.Hit | Тело с компонентом отклика на удар во что-то врезается. |
Crushform.Impact.Vehicle.Crash | Кузов автомобиля ударяется о что-то твёрдое. |
Crushform.Impact.Prop.Break | Разрушаемый объект, который не является стеклом, ломается. |
Crushform.Impact.Prop.Break.Wood | Деревянный объект разваливается, например секция деревянного забора. |
Crushform.Impact.Prop.Break.Metal | Металлический объект отламывается целиком, например панель забора из сетки-рабицы. |
Crushform.Impact.Prop.Debris | Фрагмент обломков разрушаемого объекта во что-то попадает. |
Crushform.Impact.Prop.Debris.Wood | Деревянный фрагмент обломков приземляется. |
Crushform.Impact.Prop.Debris.Metal | Металлический фрагмент обломков приземляется. |
Crushform.Impact.Glass.Crack | Стеклянная панель трескается. |
Crushform.Impact.Glass.Break | Стеклянная панель ломается и рассыпается. |
Crushform.Impact.Glass.Shard | Осколок стекла во что-то попадает. |
Crushform.Impact.Tree.Hit | Тело толкает разрушаемое дерево. |
Crushform.Impact.Tree.Break | Разрушаемое дерево ломается и начинает падать. |
Crushform.Impact.Tree.Bend | Разрушаемый столб поддаётся и остаётся наклонённым. |
Crushform.Impact.Tree.Land | Упавший ствол дерева ударяется о землю. |
Crushform.Impact.Part.Hit | Деталь автомобиля, которая качается на шарнире или оторвалась, во что-то попадает. |
Crushform.Impact.Part.Slam | Деталь автомобиля, качающаяся на шарнире, ударяется о закрытый конец хода. |
Crushform.Impact.Part.Slam.Open | Деталь автомобиля, качающаяся на шарнире и отброшенная далеко, ударяется о открытый конец хода. |
Строка набора для тега — это FCFImpactFeedbackEntry. Её Sounds — список, один из которого проигрывается случайно, поэтому для вариаций не нужен отдельный звуковой cue. Её Effect — система Niagara, которая получает float-параметр Intensity. Её Attenuation формирует звук на расстоянии.
Настройка
Заголовок раздела «Настройка»Здесь используется поставляемый набор, а затем создаётся собственная строка.
- В Content Browser набор по умолчанию находится в Plugins › Crushform Content › Impact.
- Откройте
DA_CF_ImpactFeedback. Его список Entries содержит по одной строке на тег. Найдите строкуCrushform.Impact.Prop.Break.Wood, чтобы увидеть, что хранит строка: Sounds, Effect, Attenuation, диапазоны громкости и высоты тона и фильтры.
| Impact | ||
|---|---|---|
| Entries | 18 Array elements | |
| Index [ 0 ] | ||
| Index [ 1 ] | ||
| Index [ 2 ] | ||
| Index [ 3 ] | ||
| Index [ 4 ] | ||
| Index [ 5 ] | ||
| Index [ 6 ] | ||
| Index [ 7 ] | ||
| Index [ 8 ] | ||
| Index [ 9 ] | ||
| Index [ 10 ] | ||
| Index [ 11 ] | ||
| Event Tag | Crushform.Impact.Prop.Break.Wood | |
| Sounds | 5 Array elements | |
| Effect | NS_CF_ImpactWood_Break | |
| Attenuation | SA_CF_CarImpact | |
| Volume by Intensity | 0.41.0 | |
| Pitch Range | 0.921.08 | |
| Min Intensity | ||
| Cooldown Seconds | 0.1 | |
| Max Concurrent Voices | 4 | |
| Surface Overrides | 0 Array element | |
| Index [ 12 ] | ||
| Index [ 13 ] | ||
| Index [ 14 ] | ||
| Index [ 15 ] | ||
| Index [ 16 ] | ||
| Index [ 17 ] | ||
- Чтобы сделать свой набор, выберите Add › Miscellaneous › Data Asset, укажите класс CFImpact Feedback Set и добавьте строку в Entries. Задайте её Event Tag равным нужному тегу и заполните её звуки и эффект.
- Откройте Project Settings › Plugins › Crushform Impact Feedback. Задайте Default Set равным вашему набору. Набору нужны только строки для тегов, которые вы хотите слышать. У тега без строки используется строка его ближайшего родителя, поэтому строка для
Crushform.Impactпокрывает все теги, у которых своей строки нет. - Чтобы дать автомобилю его удары, оставьте включённым Impact Feedback на адаптере, как это есть по умолчанию. Его
CF_ImpactFeedbackпроигрывает Impact Event Tag адаптера.CF_PartImpactFeedbackсохраняет собственные теги, и адаптер создаёт его только при включённом Dirt and Dents. Таблица компонентов описана на странице Основные понятия.
Использование
Заголовок раздела «Использование»В своём проекте Blueprint проигрывает удар узлом Play Impact. Он принимает тег, точку, нормаль (по умолчанию вверх), интенсивность от 0 до 1, поверхность и необязательный источник. Удары от одного источника делят общую задержку. График ниже проигрывает удар поломки дерева в точке эктора, когда срабатывает пользовательское событие.
Play Impact проигрывается только на инстансе, который его вызывает, а на выделенном сервере не проигрывается вовсе. Игра, в которой каждый игрок должен его слышать, вызывает его на каждом инстансе, например из multicast-события.
То же в C++ использует функцию библиотеки, с тегами из CFImpactTags. Блоку нужен модуль CrushformImpact в вашем Build.cs; список модулей есть на странице Установка.
#include "CFImpactFeedbackLibrary.h"#include "CFImpactTags.h"
void PlayTreeBreakHere(const UObject* WorldContext, const FVector& Location){ UCFImpactFeedbackLibrary::PlayImpact(WorldContext, CFImpactTags::Impact_Tree_Break, Location);}Сигнатура: static void PlayImpact(const UObject* WorldContextObject, FGameplayTag Tag, FVector Location, FVector Normal = FVector::UpVector, float Intensity = 1.f, EPhysicalSurface Surface = SurfaceType_Default, const UObject* Source = nullptr). UCFImpactFeedbackSubsystem::Get(WorldContext)->PlayImpact(FCFImpactEvent) — тот же вызов уровнем ниже, для кода, который строит событие сам.
Основные настройки
Заголовок раздела «Основные настройки»Настройки проекта находятся в UCFImpactFeedbackSettings. У строки и компонентов есть собственные значения, которые перечислены ниже. Значения по умолчанию — от плагина.
| Свойство | Что делает | По умолчанию |
|---|---|---|
UCFImpactFeedbackSettings::DefaultSet | Набор ударов, который проигрывается. | /Crushform/Impact/DA_CF_ImpactFeedback |
UCFImpactFeedbackSettings::MaxAudibleDistanceCm | Дальше этого расстояния в см звук не проигрывается. | 6000 |
UCFImpactFeedbackSettings::MaxEffectDistanceCm | Дальше этого расстояния в см эффект не порождается. | 8000 |
UCFImpactFeedbackSettings::MinVoiceSeconds | Наименьшее время, которое проигранный звук занимает слот голоса. | 0.25 |
UCFImpactFeedbackSettings::MaxVoiceSeconds | Наибольшее время, которое проигранный звук занимает слот голоса. | 3 |
UCFImpactFeedbackSettings::MaxSoundsPerFrame | Наибольшее число звуков, которые стартуют в одном кадре. Остальные ждут следующих кадров, самые сильные первыми. 0 выключает ограничение. | 2 |
UCFImpactFeedbackSettings::SoundQueueSeconds | Сколько звук сверх лимита кадра может ждать; после этого он отбрасывается. | 0.15 |
UCFImpactFeedbackSettings::IgnoredHitActorClasses | Удар от эктора одного из этих классов не является ударом. | пусто |
UCFImpactFeedbackSettings::bUseDefaultBreakableHost | Сопоставляет ли плагин отклик разрушаемых объектов с событиями ударов. | true |
FCFImpactFeedbackEntry::VolumeByIntensity | Множитель громкости при интенсивности 0 и при интенсивности 1. | (0.4, 1.0) |
FCFImpactFeedbackEntry::PitchRange | Диапазон случайного множителя высоты тона. | (0.92, 1.08) |
FCFImpactFeedbackEntry::MinIntensity | Интенсивность ниже этого значения ничего не проигрывает. 0 выключает фильтр. | 0 |
FCFImpactFeedbackEntry::CooldownSeconds | Время между двумя ударами одного источника. | 0.1 |
FCFImpactFeedbackEntry::MaxConcurrentVoices | Наибольшее число звуков строки, которые проигрываются одновременно. | 4 |
UCFImpactFeedbackComponent::ImpulsePerKgForFullIntensity | Импульс на килограмм, который проигрывается в полную силу. | 600 |
UCFImpactFeedbackComponent::MinImpulsePerKg | Импульс на килограмм, ниже которого удар молчит. | 50 |
UCFImpactFeedbackComponent::ContactGapSeconds | Тишина, после которой следующий удар компонента считается новым контактом. | 0.1 |
UCFImpactFeedbackComponent::ContactSpikeRatio | Внутри контакта удар проигрывается, только если его импульс в это число раз больше текущего импульса. | 2 |
UCFNetImpactFeedbackComponent::MinRelayIntervalSeconds | Наименьший промежуток между двумя ударами этого тела, которые отправляются другим игрокам, кроме заметно более сильного удара, который отправляется раньше. | 0.5 |
UCFPartImpactFeedbackComponent::OpenSlamEventTag | Событие удара при ударе о открытый конец хода детали. Пусто: там звука нет. | Crushform.Impact.Part.Slam.Open |
UCFPartImpactFeedbackComponent::SlamSpeedForFullIntensity | Скорость удара детали в см/с, при которой он проигрывается в полную силу. | 500 |
UCFPartImpactFeedbackComponent::MinSlamSpeed | Скорость в см/с, ниже которой удар детали молчит. | 40 |
Проверка работы
Заголовок раздела «Проверка работы»В любой сборке, кроме Shipping, откройте консоль клавишей тильда.
crushform.Impact.LogHits 1включает маркеры. Въедьте седаном в стену, забор или дерево. Каждый оценённый удар оставляет маркер примерно на 5 секунд: зелёный для удара при контакте, который проигрывается, жёлтый для удара внутри устойчивого контакта и красный для удара ниже минимума. Чтобы их выключить, используйтеcrushform.Impact.LogHits 0. По умолчанию значение0.stat CFImpactFeedbackпоказывает циклы ударов.- Ударьте автомобилем о стену. Вы слышите звук и видите эффект в месте контакта.
Устранение неполадок
Заголовок раздела «Устранение неполадок»На выделенном сервере ничего не проигрывается, или другие игроки ничего не слышат
Заголовок раздела «На выделенном сервере ничего не проигрывается, или другие игроки ничего не слышат»Причина. Выделенный сервер вообще не проигрывает ударов. Вызов Play Impact проигрывается только на инстансе, который его делает. Удары от компонента доходят до других игроков только через UCFNetImpactFeedbackComponent, который их передаёт.
Решение. Вызывайте Play Impact на каждом инстансе, который должен это слышать. Для ударов тела, которые должны слышать другие игроки, используйте на нём UCFNetImpactFeedbackComponent.
Тег ничего не проигрывает
Заголовок раздела «Тег ничего не проигрывает»Причина. В активном наборе нет строки для этого тега или для любого из его родителей, поэтому UCFImpactFeedbackSet::FindEntry ничего не находит. Компонент или адаптер, у которого тег очищен вручную, тоже ничего не проигрывает.
Решение. Добавьте в набор строку для тега или строку для его ближайшего родителя. Верните тег на компонент или адаптер либо оставьте поле пустым, чтобы проигрывался тег плагина по умолчанию.
Тело, к которому я добавил компонент, молчит
Заголовок раздела «Тело, к которому я добавил компонент, молчит»Причина. Здесь два случая. UCFImpactFeedbackComponent не наблюдает ни одного примитива, пока в C++ не вызван SetObservedPrimitive, поэтому компонент, добавленный только в Blueprint, молчит. UCFNetImpactFeedbackComponent наблюдает корневой примитив своего владельца, и если корень не является примитивом, он пишет эту строку и молчит:
%s: owner %s has no primitive root; its impacts stay silentРешение. Для базового компонента передайте ему примитив из C++ через SetObservedPrimitive. Для тела, которое должны слышать другие игроки, используйте UCFNetImpactFeedbackComponent и убедитесь, что корневой компонент владельца является примитивом, например мешем тела.
Удар молчит или проигрывает только эффект
Заголовок раздела «Удар молчит или проигрывает только эффект»Причина. Удар ниже Min Impulse Per Kg (50) или ниже Min Intensity строки, поэтому он молчит. Либо все Max Concurrent Voices строки заняты, и тогда удар проигрывает эффект без звука.
Решение. Уменьшите Min Impulse Per Kg или Min Intensity для строки либо увеличьте Max Concurrent Voices. Включите crushform.Impact.LogHits 1, чтобы увидеть, краснеет ли удар (ниже минимума) или вообще был оценён.
Устойчивый контакт снова и снова проигрывает удар
Заголовок раздела «Устойчивый контакт снова и снова проигрывает удар»Причина. Компонент проигрывает новый удар, только когда удар — это всплеск внутри его контакта: его импульс не меньше Contact Spike Ratio (2) текущего импульса. Контакт, который сохраняет свой импульс, не повторяется. Контакт, который прерывается дольше Contact Gap Seconds (0,1 с), считается новым.
Решение. Увеличьте Contact Gap Seconds выше нескольких шагов физики, если один удар распадается на несколько. Оставьте коэффициент всплеска по умолчанию, если устойчивый контакт всё же повторяется.
О поломках, из которых возникают эти удары, см. Заборы и объекты и Разрушаемые деревья и столбы. Собственные звуки удара автомобиля задаются на его адаптере, описанном в Основных понятиях.