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

МИРЗАБОРЫ И ОБЪЕКТЫ

Заборы и объекты

Забор — это ряд столбов и секций, проложенный по сплайну на вашем уровне. Автомобиль, который въезжает в элемент забора, ломает этот элемент: штакетина раскалывается, панель сетки-рабицы падает. Автомобиль теряет часть скорости, а обломки разлетаются в воздух.

Вид сверху на редактор с выбранным штакетным забором: его ряд штакетин идёт по S-образному сплайну, а на конце видны точки сплайна, касательный маркер и гизмо трансформации.
Ряд штакетин идёт по S-образному сплайну выбранного BP_CF_FencePicket.

На 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 30.0005
Max Piece Length Cm125.0
Min Piece Volume Cm 350.0
Cut Tilt Degrees15.0
Bake Seed1
Bake Revision1
Pieces16 Array elements
Bake Pieces
Группа Bake ассета DA_CF_FencePicket с кнопкой Bake Pieces в конце.

В категории Bake определения есть кнопка Bake Pieces. Она заменяет предыдущее запекание. Утилитарный Blueprint редактора может выполнить то же запекание статической функцией BakePieces(Definition, OutError) из CFBreakable Piece Bake Library (только в редакторе).

Здесь используется штакетный забор на Proving Ground. Чтобы сделать свой забор, см. шаг 3.

  1. В Content Browser поставляемые заборы лежат в Plugins › Crushform Content › Fences.
  2. Перетащите BP_CF_FencePicket на свой уровень или разместите ACFBreakableFence из панели Place Actors. Длина сплайна задаёт количество: забор ставит примерно одну секцию на каждые Post Spacing Cm линии. Чтобы сделать ряд длиннее, растяните сплайн.
  3. Для своего забора сначала создайте определение. В Content Browser выберите Add › Miscellaneous › Data Asset, укажите класс CFBreakable Prop Definition и назовите его. Задайте Intact Mesh равным мешу элемента, затем нажмите Bake Pieces в категории Bake. Фрагменты появятся рядом с ассетом.
  4. Выделите забор на уровне. В панели Details, в разделе Fence, задайте Span Definition равным вашему определению. Задайте и Post Definition, если у линии есть столбы.
Fence
Post DefinitionNone
Span DefinitionDA_CF_FencePicket
Post Spacing Cm0.0
Группа Fence размещённого забора BP_CF_FencePicket с её определением секции и шагом столбов.
  1. Задайте 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 и уменьшите ограничения по массе и скорости под тело, которое должно ломать элемент.

О самих фрагментах см. Обломки. О звуках и эффектах поломки см. Отклик на удары.