НАЧАЛО РАБОТЫСВОЙ АВТОМОБИЛЬ
Свой автомобиль
Используйте эту страницу для автомобиля, который не является пешкой Chaos Vehicles. Для пешки Chaos Vehicles Crushform Chaos Vehicle Adapter читает колёса из компонента движения, и Быстрый старт описывает его подключение.
Перед началом
Заголовок раздела «Перед началом»- Корневой компонент эктора — симулируемый кузов. Вмятины и краска измеряются на нём, а для вмятины нужен профиль деформации.
- Настройте материалы, как в руководстве Быстрый старт.
- Колёса — компоненты эктора: меш или scene-компонент, который поворачивается вместе с колесом.
- Для C++ добавьте в свой
Build.csмодули Crushform, которые вы вызываете, как в руководстве Установка.
С Crushform Vehicle Adapter
Заголовок раздела «С Crushform Vehicle Adapter»Адаптер трассирует поверхность под каждым колесом, которое вы перечислили. Он создаёт вмятины и грязь, стекло, шины, звуки, разрушение объектов и отклик на удары, а также отвечает на их вопросы об автомобиле.
- Add › Crushform Vehicle Adapter. Добавьте его к эктору.
- Задайте
UCFVehicleAdapterComponent::Wheels: одинFCFAdapterWheelна каждое колесо. В Details раскройте Wheels и добавьте по одному элементу на колесо. В каждом элементе выберите колесо в списке Wheel, который показывает scene-компоненты эктора, и задайте Radius, радиус шины в сантиметрах. Радиус 0 означает половину высоты границ меша колеса. Задавайте радиус для колеса, которое уже вращается.
- Задайте
GroundChannel, канал, по которому колёса трассируют землю (по умолчанию Visibility), иGroundProbeMargin, по умолчанию 2 см. Трассировка начинается от ступицы, поэтому шина, которая находится на таком расстоянии над землёй, всё ещё касается её. Или вызовитеUCFVehicleAdapterComponent::SetWheelsво время игры со значениямиFCFAdapterWheelState. Это работает и до BeginPlay. - Задайте
AuthorityиRamAllowanceMps.Server— по умолчанию: сервер симулирует автомобиль и оценивает его удары. СOwningClientинстанс, на котором ведут автомобиль, симулирует его и сообщает о своих ударах, а сервер принимает отчёт, только если изменение скорости не превышает недавнюю пиковую скорость автомобиля плюсRamAllowanceMps(по умолчанию 15 м/с), с поправкой в большую сторону для более лёгкого кузова, который уступает. Затем задайте профили и флаги функций. ПустыеDeformProfileилиTireProfileберут значение проекта по умолчанию. Каждый флаг функции включён по умолчанию; каждый выключает компонент, который он называет. - Привяжите событие
OnDamageChangedв Blueprint, если автомобиль должен реагировать на повреждения. Оно срабатывает, когда меняются повреждения кузова, и никогда не срабатывает без Dirt and Dents.
Сообщите адаптеру, что делает автомобиль
Заголовок раздела «Сообщите адаптеру, что делает автомобиль»Адаптер не видит ваше управление, поэтому сообщите ему:
- Вызовите
UCFVehicleAdapterComponent::SetBrakingсо значением от 0 до 1. FX качения выбрасывают больше грязи, пока автомобиль тормозит. - Вызовите
UCFVehicleAdapterComponent::SetCabinMuffledсо значением true, пока слушатель сидит в салоне. Это приглушает звук качения и звук двигателя. - Звук двигателя читает пять событий:
GetEngineRunState(Off, Cranking или Running),GetEngineRPM,GetEngineIdleRPM,GetEngineMaxRPMиGetEngineLoad. Адаптер отвечает off и нулём. Переопределите их в Blueprint-наследнике адаптера или в C++.
Подавайте данные из компонента движения
Заголовок раздела «Подавайте данные из компонента движения»Если ваши колёса симулирует физическая система, отличная от встроенной трассировки, переопределите четыре события колёс адаптера: UCFVehicleAdapterComponent::BuildWheelContacts, CollectWheelMeshes, BuildTireWheels и BuildLoadRatios. Адаптер Chaos делает то же самое для Chaos Vehicles.
Для каждого колеса BuildWheelContacts заполняет один FCFWheelContact за кадр:
Point: где шина касается земли, в мировом пространстве, см. Читается только покаbGroundedистинно.Radius: радиус шины, см.bGrounded: ложь, пока колесо в воздухе. Колесо в воздухе не оставляет грязи.PhysicalMaterial: поверхность под колесом. Null берёт стандартные скорости.SurfaceSpeed: скорость поверхности шины, м/с, положительная, когда она катит автомобиль вперёд.GroundSpeed: скорость ступицы над землёй, м/с. Если меньше 0, используется скорость автомобиля.WheelIndex: номер колеса, с 0. Он не меняется за всё время жизни колеса.
CollectWheelMeshes возвращает меши колёс. Они получают грязь и никогда не деформируются. BuildTireWheels возвращает меш каждой шины, физический радиус и HostIndex, а также bAcceptsPush; когда его ставить, сказано в руководстве Host-интерфейсы. BuildLoadRatios возвращает силу контакта, делённую на номинальную нагрузку, по HostIndex; отсутствующий или отрицательный элемент держит коэффициент нагрузки этого колеса равным 1.
Без адаптера: host-интерфейсы
Заголовок раздела «Без адаптера: host-интерфейсы»Используйте host-интерфейсы, когда у автомобиля свой набор компонентов и вы не хотите адаптер. Вы добавляете компоненты Crushform сами и отвечаете на их вопросы в самом экторе или в одном из его компонентов. Интерфейсы находятся в модуле Crushform, кроме ICFTireHost и ICFTireViewer (CrushformTire) и ICFEngineHost (CrushformEngine).
Какие компоненты добавить
Заголовок раздела «Какие компоненты добавить»| Компонент | Модуль | Что нужно |
|---|---|---|
UCFDeformComponent | Crushform | Профиль деформации: без него компонент ничего не делает. Корневой компонент эктора — симулируемый кузов. |
UCFGlassUnitsComponent | Crushform | Стеклянные панели, которые являются дочерними UCFGlassComponent эктора. GetCrushformGlass эктора возвращает этот компонент. Нужен компонент деформации. |
UCFTireComponent | CrushformTire | ICFTireHost на экторе. Без него шины остаются круглыми. Профиль шин или значение проекта по умолчанию. |
UCFRollingAudioComponent | CrushformWheel | ICFWheelHost на экторе. Звук каждой поверхности берётся из таблицы поверхностей проекта. |
UCFRollingFXComponent | CrushformWheel | ICFWheelHost на экторе. Эффект каждой поверхности берётся из таблицы поверхностей проекта. |
UCFPropContactComponent | Crushform | Корневой примитив эктора как кузов. ICFBreakerHost необязателен. |
UCFImpactFeedbackComponent | CrushformImpact | Примитив, удары которого он сообщает, задаётся через SetObservedPrimitive. Его EventTag проигрывает звук; пустое значение означает отсутствие звука. |
UCFEngineAudioComponent | CrushformEngine | ICFEngineHost на экторе. Звуковой профиль или значение проекта по умолчанию. |
На кузове автомобиля адаптер использует UCFNetImpactFeedbackComponent вместо UCFImpactFeedbackComponent. Он сообщает об ударах кузова только на инстансе, который симулирует кузов, а остальные инстансы проигрывают ретранслированную копию.
В меню Add компоненты отклика на удары — CFImpact Feedback, CFNet Impact Feedback и компонент для деталей — стоят в категории Custom, а не Crushform.
Шесть host-интерфейсов:
| Интерфейс | Кого спрашивает | Что отвечает |
|---|---|---|
ICFDeformHost | UCFDeformComponent, сетевой отклик на удары | Какой инстанс симулирует кузов, игнорируемые экторы, правдоподобен ли отчёт, какие меши деформируются, меши колёс, стекло |
ICFWheelHost | слой грязи, UCFRollingAudioComponent, UCFRollingFXComponent | Колёса кадра в виде значений FCFWheelContact |
ICFBreakerHost | UCFPropContactComponent | Симулирует ли этот инстанс кузов, контактное тело, маршрут отчёта, компонент деформации, которым вминается разрушенный элемент |
ICFTireHost | UCFTireComponent | Колёса, смещения и выталкивания, которые записываются обратно, коэффициенты нагрузки, сцепка |
ICFTireViewer | бюджет шин, на пешке | Автомобиль, в котором едет пешка, или null, если он пешком |
ICFEngineHost | UCFEngineAudioComponent | Состояние двигателя: режим работы, обороты, холостые и максимальные обороты, нагрузка |
Компонент находит свой host-объект в таком порядке. Сначала host-объект, заданный через SetCrushformHost до BeginPlay. Затем host-объект, зарегистрированный для эктора в UCFHostRegistry. Затем сам эктор, если он реализует интерфейс. Иначе host-объекта нет. Каждое событие отвечает ECFHostAnswer: Default означает, что компонент решает так, будто host-объекта нет, а Yes или No переопределяют это.
В Blueprint
Заголовок раздела «В Blueprint»- Откройте Blueprint эктора и перейдите в Class Settings. В разделе Implemented Interfaces нажмите Add и выберите интерфейс, например CFDeform Host, затем CFWheel Host.
- Функции интерфейсов появляются в My Blueprint в разделе Interfaces › Crushform с их C++-именами без пробелов, например
GatherCrushformWheelMeshes. Дважды щёлкните по функции, чтобы реализовать её. ЗначениеECFHostAnswer, которое вы не трогали, возвращаетDefault. Список, который вы не трогали, ничего не собирает.
- У
GatherCrushformWheelMeshesесть выходной массив, поэтому это функция. Соберите массив из четырёх мешей колёс и подключите его к выходу узла Return.
Реализуйте интерфейсы у эктора и переопределите _Implementation каждого события, на которое отвечаете. Этот класс отвечает за меши колёс и контакты колёс четырёхколёсного автомобиля.
#pragma once
#include "CoreMinimal.h"#include "CFDeformHost.h"#include "CFWheelHost.h"#include "GameFramework/Actor.h"#include "YourVehicle.generated.h"
class UMeshComponent;class UStaticMeshComponent;
UCLASS()class AYourVehicle : public AActor, public ICFDeformHost, public ICFWheelHost{ GENERATED_BODY()
public: virtual void GatherCrushformWheelMeshes_Implementation(TArray<UMeshComponent*>& OutMeshes) const override; virtual void GatherCrushformWheelContacts_Implementation(TArray<FCFWheelContact>& OutContacts) const override;
/** The four wheels, in WheelIndex order. Fill it in the constructor with the wheel components you create, or in Blueprint once they exist. */ UPROPERTY(VisibleAnywhere) TArray<TObjectPtr<UStaticMeshComponent>> Wheels;
/** Tyre radius, cm. */ UPROPERTY(EditAnywhere) float WheelRadius = 35.f;
/** The speed of each wheel's surface, m/s, from your vehicle model. */ TArray<float> WheelSurfaceSpeeds;};Тело GatherCrushformWheelContacts трассирует вниз от ступицы каждого колеса и заполняет один FCFWheelContact на колесо. Колесо в воздухе оставляет bGrounded ложным, а Point и PhysicalMaterial не задаются.
#include "YourVehicle.h"#include "Components/StaticMeshComponent.h"#include "Engine/World.h"#include "PhysicalMaterials/PhysicalMaterial.h"
void AYourVehicle::GatherCrushformWheelMeshes_Implementation(TArray<UMeshComponent*>& OutMeshes) const{ for (UStaticMeshComponent* Wheel : Wheels) { OutMeshes.Add(Wheel); }}
void AYourVehicle::GatherCrushformWheelContacts_Implementation(TArray<FCFWheelContact>& OutContacts) const{ UWorld* World = GetWorld(); if (!World) { return; }
// The physical material comes back only when the query asks for it. FCollisionQueryParams Params(SCENE_QUERY_STAT(YourVehicleWheel), false, this); Params.bReturnPhysicalMaterial = true;
for (int32 Index = 0; Index < Wheels.Num(); ++Index) { const UStaticMeshComponent* Wheel = Wheels[Index]; if (!IsValid(Wheel)) { continue; }
// Trace down from the hub, past the tyre radius. const FVector Hub = Wheel->GetComponentLocation(); const FVector TraceEnd = Hub - FVector(0.f, 0.f, WheelRadius + 20.f); FHitResult Hit;
FCFWheelContact Contact; Contact.WheelIndex = Index; Contact.Radius = WheelRadius; Contact.SurfaceSpeed = WheelSurfaceSpeeds.IsValidIndex(Index) ? WheelSurfaceSpeeds[Index] : 0.f; Contact.bGrounded = World->LineTraceSingleByChannel(Hit, Hub, TraceEnd, ECC_Visibility, Params); if (Contact.bGrounded) { Contact.Point = Hit.ImpactPoint; Contact.PhysicalMaterial = Hit.PhysMaterial.Get(); }
OutContacts.Add(Contact); }}Код, которому нужны колёса эктора, спрашивает его host-объект через Execute_, а не вызывает событие по имени через указатель:
#include "CFHostRegistry.h"#include "CFWheelHost.h"
TArray<FCFWheelContact> Contacts;if (UObject* Host = UCFHostRegistry::FindHost(this, *UCFWheelHost::StaticClass())){ ICFWheelHost::Execute_GatherCrushformWheelContacts(Host, Contacts);}Подводные камни
Заголовок раздела «Подводные камни»- Второй host-объект для того же эктора и интерфейса заменяет первый, с предупреждением.
- Blueprint-host-объект не отвечает в превью редактора. Превью не запускает его скрипт, поэтому раскладка решётки в Details и редактор зон не видят его ответов. Проверяйте результат в Play.
- Не вызывайте событие интерфейса по имени через указатель на интерфейс. Используйте функцию
Execute_или аксессор компонента.
Ключевые настройки
Заголовок раздела «Ключевые настройки»Это свойства адаптера. Собственные настройки адаптера находятся в Details компонента адаптера.
| Свойство | По умолчанию | Что делает |
|---|---|---|
UCFVehicleAdapterComponent::Wheels | пусто | Колёса, которые трассирует адаптер: компонент и Radius для каждого. |
GroundChannel | Visibility | Канал, по которому колёса трассируют землю. |
GroundProbeMargin | 2 см | На каком расстоянии над землёй шина ещё касается её. |
Authority | Server | Какой инстанс симулирует автомобиль и оценивает его удары. |
RamAllowanceMps | 15 м/с | При OwningClient: насколько сообщённый удар может превышать недавнюю пиковую скорость. |
DeformProfile | проект по умолчанию | Вмятины и грязь кузова. |
TireProfile | проект по умолчанию | Шины. |
EngineSoundProfile | проект по умолчанию | Звук двигателя. |
bDirtAndDents, bGlass, bTires, bRollingSound, bRollingFX, bEngineSound, bImpactFeedback, bBreaksProps | все включены | Каждый выключает компонент, который он называет. |
ImpactImpulsePerKgForFullIntensity | 600 см/с | Изменение скорости при ударе, который проигрывается в полную силу. |
ImpactMinImpulsePerKg | 50 см/с | Изменение скорости, ниже которого удар ничего не проигрывает. |
PropContactMinSpeedCmS | 50 см/с | Ниже этой скорости автомобиль не ломает объекты. |
Проверка работы
Заголовок раздела «Проверка работы»- Откройте уровень с вашим автомобилем и нажмите Play.
- Откройте консоль клавишей тильда и выполните
Crushform.Stats. Команда выводит занятые слоты атласа и счётчики ударов каждого повреждаемого эктора. - Выполните
Crushform.Debug 1. Команда рисует повреждённые узлы решётки кузова.Crushform.Debug 2рисует все узлы. - Выполните
Crushform.DebugImpact 10 <name>, чтобы ударить эктор, чьё имя содержит<name>, со скоростью 10 м/с, на расстоянии до 100 м. Без имени удар приходится на эктора под прицелом. Команда никогда не бьёт по пешке, которой вы управляете, поэтому проверяйте свой автомобиль, въезжая в стену, как в шаге 5 руководства Быстрый старт. Это чит: он есть в каждой сборке, кроме Shipping, включая редактор. - Проедьте по поверхности из
PM_CF_Mud. Колёса должны реагировать на грязь так, как это задано в таблице поверхностей проекта.


