The vehicle floated 3.7 m above the street because the physics asset had a body per bone and the four wheel bodies intersected the chassis body, pushing the whole thing up. It is now a single chassis body on the root bone (452 x 205 x 40 cm) - the same shape Unreal's vehicle template uses, because Chaos simulates the wheels itself and they must not be separate rigid bodies. Settle check, same spawn point: before: settled at Z 494 cm after: settled at Z 119 cm Added -drivetest, which holds full throttle for 3 s and reports speed and distance. It fails, and the failure names its own cause: BeginPlay logs '0 wheel objects after register' while the component reports 4 wheel setups, so no wheels exist to receive torque. Recorded in TODO.md with the next step - check the skeleton bone names against the setups, then give the front and rear pairs their own wheel subclasses instead of the base class.
72 lines
2.5 KiB
C++
72 lines
2.5 KiB
C++
#include "GigLineVehicleBuilder.h"
|
|
|
|
#if WITH_EDITOR
|
|
#include "AssetToolsModule.h"
|
|
#include "Engine/SkeletalMesh.h"
|
|
#include "PhysicsAssetUtils.h"
|
|
#include "PhysicsEngine/PhysicsAsset.h"
|
|
#include "PhysicsEngine/BodySetup.h"
|
|
#include "PhysicsEngine/SkeletalBodySetup.h"
|
|
#include "Engine/SkeletalMesh.h"
|
|
|
|
#include "UObject/Package.h"
|
|
#endif
|
|
|
|
UPhysicsAsset* UGigLineVehicleBuilder::BuildPhysicsAsset(USkeletalMesh* Mesh,
|
|
const FString& PackagePath,
|
|
const FString& AssetName)
|
|
{
|
|
#if WITH_EDITOR
|
|
if (!Mesh)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("GigLine vehicle: no skeletal mesh given"));
|
|
return nullptr;
|
|
}
|
|
|
|
const FString FullName = PackagePath / AssetName;
|
|
UPackage* Package = CreatePackage(*FullName);
|
|
if (!Package)
|
|
{
|
|
UE_LOG(LogTemp, Warning, TEXT("GigLine vehicle: could not create package %s"), *FullName);
|
|
return nullptr;
|
|
}
|
|
UPhysicsAsset* PhysicsAsset = NewObject<UPhysicsAsset>(Package, *AssetName,
|
|
RF_Public | RF_Standalone | RF_Transactional);
|
|
|
|
// ONE body on the chassis bone, which is what Unreal's own vehicle template uses.
|
|
// The first attempt let FPhysicsAssetUtils build a body per bone and the car settled
|
|
// 3.7 m above the road: the four wheel bodies were intersecting the chassis body and
|
|
// pushing the whole vehicle up. Chaos drives the wheels itself, so they must not be
|
|
// separate rigid bodies here.
|
|
const FBoxSphereBounds Bounds = Mesh->GetBounds();
|
|
const FVector Extent = Bounds.BoxExtent;
|
|
const FName ChassisBone(TEXT("root"));
|
|
|
|
USkeletalBodySetup* Body = NewObject<USkeletalBodySetup>(PhysicsAsset, ChassisBone,
|
|
RF_Public | RF_Transactional);
|
|
Body->BoneName = ChassisBone;
|
|
// A box slightly under the mesh bounds: a body that is exactly the bounds sits on the
|
|
// ground plane and reads as floating because the mesh has wheels below the sills.
|
|
FKBoxElem Box;
|
|
Box.X = Extent.X * 1.9f;
|
|
Box.Y = Extent.Y * 1.8f;
|
|
Box.Z = Extent.Z * 0.55f;
|
|
Box.Center = FVector(0.f, 0.f, -Extent.Z * 0.25f);
|
|
Body->AggGeom.BoxElems.Add(Box);
|
|
PhysicsAsset->SkeletalBodySetups.Add(Body);
|
|
|
|
UE_LOG(LogTemp, Warning,
|
|
TEXT("GigLine vehicle: chassis body %.0f x %.0f x %.0f cm on bone '%s'"),
|
|
Box.X, Box.Y, Box.Z, *ChassisBone.ToString());
|
|
|
|
PhysicsAsset->MarkPackageDirty();
|
|
UE_LOG(LogTemp, Warning, TEXT("GigLine vehicle: physics asset %s with %d bodies"),
|
|
*FullName, PhysicsAsset->SkeletalBodySetups.Num());
|
|
return PhysicsAsset;
|
|
#else
|
|
UE_LOG(LogTemp, Warning,
|
|
TEXT("GigLine vehicle: physics asset generation is editor-only"));
|
|
return nullptr;
|
|
#endif
|
|
}
|