МИРЗАБОРЫ И ОБЪЕКТЫ
Заборы и объекты
Что это делает
Заголовок раздела «Что это делает»Забор — это ряд столбов и секций, проложенный по сплайну на вашем уровне. Автомобиль, который въезжает в элемент забора, ломает этот элемент: штакетина раскалывается, панель сетки-рабицы падает. Автомобиль теряет часть скорости, а обломки разлетаются в воздух.
На Proving Ground есть два забора такого рода: деревянный штакетный и забор из сетки-рабицы. Оба поставляются как BP_CF_FencePicket и BP_CF_FenceChainLink.
Как это работает
Заголовок раздела «Как это работает»Забор — это эктор ACFBreakableFence. Его Spline задаёт линию. Эктор расставляет столбы и секции вдоль неё, и каждый столб или секция — это один элемент. У элемента есть набор уровней: от целого до последней разбитой формы. Удары повышают уровень элемента, но не выше его верхнего уровня.
- Определения. Из чего состоит элемент, задаётся ассетом данных класса
UCFBreakablePropDefinition. Забор принимает одно определение для секций и, по желанию, одно для столбов. Определение хранит меш и правила: как ломается элемент, что теряет автомобиль, когда элемент возвращается. - Раскладка. Линия превращается в элементы, когда забор строится в редакторе. Раскладка сохраняется вместе с эктором. В сетевой игре забор не раскладывается заново: его раскладка берётся из сохранённой.
- Запечённые фрагменты. Фрагменты, которые выбрасывает элемент, создаются из его целого меша командой Bake Pieces определения. Запекание сохраняет их как ассеты рядом с определением. Определение, которое не запечено, фрагментов не выбрасывает.
- Автомобили. Автомобиль, который въезжает в элемент, ломает его, если контакт достаточно быстрый. Каждый сломанный элемент забирает долю скорости автомобиля, а элемент может оставить вмятину на кузове.
- Любое тело. Определение с включённым Breaks from Any Body ломается от любого физического тела или идущей пешки, которые достаточно тяжелы и быстры, а не только от автомобиля.
| Bake | ||
|---|---|---|
| Bake as Single Piece | ||
| Density Kg Per Cm 3 | 0.0005 | |
| Max Piece Length Cm | 125.0 | |
| Min Piece Volume Cm 3 | 50.0 | |
| Cut Tilt Degrees | ||
| Bake Seed | 1 | |
| Bake Revision | 1 | |
| Pieces | 16 Array elements | |
В категории Bake определения есть кнопка Bake Pieces. Она заменяет предыдущее запекание. Утилитарный Blueprint редактора может выполнить то же запекание статической функцией BakePieces(Definition, OutError) из CFBreakable Piece Bake Library (только в редакторе).
Настройка
Заголовок раздела «Настройка»Здесь используется штакетный забор на Proving Ground. Чтобы сделать свой забор, см. шаг 3.
- В Content Browser поставляемые заборы лежат в Plugins › Crushform Content › Fences.
- Перетащите
BP_CF_FencePicketна свой уровень или разместитеACFBreakableFenceиз панели Place Actors. Длина сплайна задаёт количество: забор ставит примерно одну секцию на каждые Post Spacing Cm линии. Чтобы сделать ряд длиннее, растяните сплайн. - Для своего забора сначала создайте определение. В Content Browser выберите Add › Miscellaneous › Data Asset, укажите класс CFBreakable Prop Definition и назовите его. Задайте Intact Mesh равным мешу элемента, затем нажмите Bake Pieces в категории Bake. Фрагменты появятся рядом с ассетом.
- Выделите забор на уровне. В панели Details, в разделе Fence, задайте Span Definition равным вашему определению. Задайте и Post Definition, если у линии есть столбы.
| Fence | ||
|---|---|---|
| Post Definition | None | |
| Span Definition | DA_CF_FencePicket | |
| Post Spacing Cm | 0.0 | |
- Задайте Post Spacing Cm равным расстоянию между столбами. При
0используется длина тайла определения секции. Забор погружает столбы в землю на Post Sink Cm (по умолчанию 5 см) и привязывает их к земле, когда включено Snap to Ground.
Использование
Заголовок раздела «Использование»Blueprint может сломать элемент ударом. Трассируйте элемент командой Line Trace For Objects по типу объекта элементов, а не по каналу. Профиль элемента по умолчанию — OverlapAllDynamic: его элементы — объекты WorldDynamic, которые перекрываются со всеми каналами, поэтому трассировка по каналу, например по Visibility, никогда в них не останавливается. Задайте трассировке тип объекта элементов, по умолчанию WorldDynamic, затем примените удар к элементу, который нашла трассировка, через ApplyHitResultOnAuthority. Функция принимает Hit Result из трассировки, Strength и Hit Kind: вид должен иметь строку в Hit Responses определения, а сила должна достигать одного из Hit Level Thresholds. Запускайте это из пользовательского события и вызывайте ApplyHitResultOnAuthority из серверного кода, а не с клиента: функция статическая и выполняется только на авторитете.
В C++ тот же вызов применяет удар к элементу без трассировки:
#include "CFBreakableInstancesComponent.h"#include "CFBreakableTypes.h"
// Needs the CrushformBreakable module in your Build.cs (see Installation).void BreakFirstUnitOnServer(UCFBreakableUnitsComponent* Units, const FVector& Location, const FVector& Direction){ if (IsValid(Units) && Units->GetUnitCount() > 0) { FCFBreakableHit Hit; Hit.Location = Location; Hit.Direction = Direction; Hit.Strength = 900.f; Hit.Kind = FName(TEXT("Bullet")); Units->ApplyHitOnAuthority(0, Hit); }}Сигнатура: virtual bool ApplyHitOnAuthority(int32 UnitIndex, const FCFBreakableHit& Hit) у UCFBreakableUnitsComponent. FCFBreakableHit содержит Location, Direction, Strength и Kind. Получите компонент забора из эктора через Fence->GetBreakableInstances(); это UCFBreakableInstancesComponent, подкласс UCFBreakableUnitsComponent.
Вид без строки в Hit Responses ничего не делает, а элемент поднимается только теми Hit Level Thresholds, которых достигает удар. Поэтому перед тестом добавьте в Hit Responses определения строку для своего вида с порогами, которые достигает ваша сила. Вид Bullet в примере — только пример.
Основные настройки
Заголовок раздела «Основные настройки»Настройки определения находятся в его панели Details. Настройки забора — на экторе забора. Значения по умолчанию — от плагина.
| Свойство | Что делает | По умолчанию |
|---|---|---|
ACFBreakableFence::PostSpacingCm | Расстояние между столбами. 0 использует длину тайла секции. | 0 |
ACFBreakableFence::bSnapToGround | Привязываются ли столбы и секции к земле под линией. | true |
ACFBreakableFence::PostSinkCm | На какую глубину столбы уходят в землю. | 5 |
UCFBreakablePropDefinition::TileLengthCm | На каком расстоянии вдоль забора стоят соседние копии меша. 0 использует собственную длину меша по X. | 0 |
UCFBreakablePropDefinition::VehicleSpeedLossFraction | Доля скорости автомобиля, которая теряется на каждый сломанный элемент. | 0.025 |
UCFBreakablePropDefinition::MaxVehicleSpeedLossCmS | Наибольшая скорость в см/с, которую один элемент забирает у автомобиля. | 150 |
UCFBreakablePropDefinition::VehicleDentSpeedFraction | Доля скорости автомобиля, переходящая в элемент, который оставляет вмятину на кузове. 0 означает, что элемент никогда не оставляет вмятину. | 0.5 |
UCFBreakablePropDefinition::bBreaksFromAnyBody | Ломается ли элемент от любого физического тела или идущей пешки. | false |
UCFBreakablePropDefinition::AnyBodyMinMassKg | Самое лёгкое тело, от которого элемент ломается в режиме любого тела. | 20 |
UCFBreakablePropDefinition::AnyBodyMinSpeedCmS | Самое медленное тело, от которого элемент ломается в режиме любого тела, в см/с. | 300 |
UCFBreakablePropDefinition::PawnMinSpeedCmS | Самая медленная идущая пешка, которая ломает элемент, в см/с. | 250 |
UCFBreakablePropDefinition::RespawnDelaySeconds | Сколько сломанный элемент остаётся лежать. 0 означает, что он никогда не вернётся. | 300 |
UCFBreakableDefinition::HitLevelThresholds | Сила внешнего удара, нужная, чтобы поднять элемент до каждого уровня: первая запись — до уровня 1, следующая — до уровня 2. | пусто |
UCFBreakableDefinition::HitResponses | Как каждый вид внешнего удара действует на элементы. Вид без строки ничего не делает. | пусто |
UCFBreakableDefinition::bBakeAsSinglePiece | Запечь весь целый меш как один фрагмент без распиловки. | false |
UCFBreakableDefinition::MaxPieceLengthCm | Острова длиннее этого распиливаются на части. | 60 |
UCFBreakableDefinition::DensityKgPerCm3 | Масса фрагмента — запечённый объём, умноженный на эту плотность. | 0.0005 |
UCFBreakableSettings::UnitCollisionProfile | Профиль коллизии экземпляров элементов. | None (используется OverlapAllDynamic) |
Настройки проекта находятся в Project Settings › Plugins › Crushform Breakable, в группах Units, Any Body и Respawn. Сломанный элемент возвращается, если его определение это позволяет, когда ни одна пешка игрока не находится ближе RespawnClearRadiusCm (4000 см) и ни одно тело из RespawnBlockingObjectTypes не перекрывает его место.
Проверка работы
Заголовок раздела «Проверка работы»В любой сборке, кроме Shipping, откройте консоль клавишей тильда.
stat CFBreakableInstancesпоказывает циклы Breakable Respawn Check и any-body.stat CFPropContactпоказывает сторону автомобиля.- Въедьте в
BP_CF_FencePicket. Элемент разваливается, и его фрагменты разлетаются. - Въедьте в
BP_CF_FenceChainLink. Его панель падает.
Режим отладки может вернуть сразу все сломанные объекты в мире: кнопка Respawn props под World в его панели. См. Режим отладки.
Устранение неполадок
Заголовок раздела «Устранение неполадок»У забора нет элементов
Заголовок раздела «У забора нет элементов»Причина. У забора нет сохранённой раскладки, а игра сетевая. Тогда в логе появляется строка:
%s: no saved layout; a networked fence must be placed and laid out in the editorОдиночная игра раскладывает забор во время работы. Сетевая игра этого не делает, иначе каждый инстанс выбрал бы свои элементы.
Решение. Разместите забор в редакторе, с заданными сплайном и определением секции, и дайте раскладке построиться. Сохраните уровень. Раскладка сохраняется вместе с забором.
Забор короче своей линии
Заголовок раздела «Забор короче своей линии»Причина. Линия требует больше элементов, чем может вместить забор, а это 256. При наличии столбов это 127 секций. Тогда в логе появляется строка:
%s: %d spans requested, capped to %d; split the line into several fencesРешение. Разбейте линию на несколько заборов, в каждом из которых меньше секций.
Сломанный элемент не выбрасывает фрагментов
Заголовок раздела «Сломанный элемент не выбрасывает фрагментов»Причина. Определение элемента не запечено. Определение без запечённых фрагментов их не создаёт. Поломка всё равно происходит, но выбрасывать нечего.
Решение. Нажмите Bake Pieces в категории Bake определения. Запекание заменяет предыдущее, поэтому запекайте заново после изменения меша или настроек запекания.
Элемент не ломается от тела, которое не является автомобилем
Заголовок раздела «Элемент не ломается от тела, которое не является автомобилем»Причина. bBreaksFromAnyBody выключен в определении. Либо тело легче AnyBodyMinMassKg, либо медленнее AnyBodyMinSpeedCmS, либо пешка медленнее PawnMinSpeedCmS.
Решение. Включите Breaks from Any Body и уменьшите ограничения по массе и скорости под тело, которое должно ломать элемент.
О самих фрагментах см. Обломки. О звуках и эффектах поломки см. Отклик на удары.
