fix(collision): terrain bbox proxy buried the whole street
The player never fell through - it stood on an invisible 8 m box. The imported Terrain_DEM carried only a bounding-box simple collision proxy, so every downward trace in the block hit Demo_Terrain_DEM at Z 819 (the mesh bbox max) and the road/sidewalk underneath were unreachable. The view from up there looked plausible, which is why it read as working. - add UGigLineAssetTools (C++): set complex-as-simple collision on a static mesh; UE 5.8 exposes ECollisionTraceFlag, not bUseComplexAsSimpleCollision, and Python cannot set it at all. - builder forces + saves the terrain asset as complex-as-simple (the flag lives on the asset, so saving only the .umap loses it). - spawn (-13336, -1150, 600): inside the carved corridor; lands on the road at Z 456 (feet 368 on road top 366). - HighResShot 1280x720, not "1280 720" (that is multiplier 1280). - keep SIM + single ground-probe diagnostics (TEMP QA).
This commit is contained in:
1 parent
2bab0fb0cd
commit
2bb1e74814
14 files changed
+157
-21
No files matched your search
@@ -0,0 +1,65 @@
|
||||
#include "GigLineAssetTools.h"
|
||||
|
||||
#include "Engine/StaticMesh.h"
|
||||
#include "PhysicsEngine/BodySetup.h"
|
||||
#include "StaticMeshResources.h"
|
||||
|
||||
void UGigLineAssetTools::SetComplexCollisionAsSimple(UStaticMesh* Mesh, bool bEnable)
|
||||
{
|
||||
if (!Mesh)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UBodySetup* BodySetup = Mesh->GetBodySetup();
|
||||
if (!BodySetup)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BodySetup->CollisionTraceFlag = bEnable ? CTF_UseComplexAsSimple : CTF_UseSimpleAndComplex;
|
||||
BodySetup->InvalidatePhysicsData();
|
||||
BodySetup->CreatePhysicsMeshes();
|
||||
Mesh->MarkPackageDirty();
|
||||
Mesh->PostEditChange();
|
||||
}
|
||||
|
||||
void UGigLineAssetTools::ClearSimpleCollision(UStaticMesh* Mesh)
|
||||
{
|
||||
if (!Mesh)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UBodySetup* BodySetup = Mesh->GetBodySetup();
|
||||
if (!BodySetup)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BodySetup->AggGeom.EmptyElements();
|
||||
BodySetup->InvalidatePhysicsData();
|
||||
BodySetup->CreatePhysicsMeshes();
|
||||
Mesh->MarkPackageDirty();
|
||||
Mesh->PostEditChange();
|
||||
}
|
||||
|
||||
FString UGigLineAssetTools::GetCollisionComplexity(UStaticMesh* Mesh)
|
||||
{
|
||||
if (!Mesh)
|
||||
{
|
||||
return TEXT("no mesh");
|
||||
}
|
||||
|
||||
const UBodySetup* BodySetup = Mesh->GetBodySetup();
|
||||
if (!BodySetup)
|
||||
{
|
||||
return TEXT("no body setup");
|
||||
}
|
||||
|
||||
const int32 Flag = static_cast<int32>(BodySetup->CollisionTraceFlag.GetValue());
|
||||
if (Flag == CTF_UseComplexAsSimple) { return TEXT("UseComplexAsSimple"); }
|
||||
if (Flag == CTF_UseSimpleAsComplex) { return TEXT("UseSimpleAsComplex"); }
|
||||
if (Flag == CTF_UseSimpleAndComplex) { return TEXT("UseSimpleAndComplex"); }
|
||||
return TEXT("ProjectDefault");
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "GigLineAssetTools.generated.h"
|
||||
|
||||
class UStaticMesh;
|
||||
|
||||
/**
|
||||
* Small editor-side helpers for the headless asset pipeline scripts.
|
||||
*
|
||||
* Exposed to Python so tools can fix up imported meshes that the Interchange
|
||||
* importer gives unusable default collision. The terrain is the motivating
|
||||
* case: without complex-as-simple it gets a bounding-box proxy, so the whole
|
||||
* street sits under an invisible 8 m box and the player walks on the box lid.
|
||||
*/
|
||||
UCLASS()
|
||||
class GIGLINE_API UGigLineAssetTools : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Make collision trace against the mesh triangles instead of a proxy hull. */
|
||||
UFUNCTION(BlueprintCallable, Category = "GigLine|Assets")
|
||||
static void SetComplexCollisionAsSimple(UStaticMesh* Mesh, bool bEnable = true);
|
||||
|
||||
/** Drop any generated simple collision (hulls/boxes) from the mesh. */
|
||||
UFUNCTION(BlueprintCallable, Category = "GigLine|Assets")
|
||||
static void ClearSimpleCollision(UStaticMesh* Mesh);
|
||||
|
||||
/** Report the current collision complexity: "SimpleAndComplex", "Simple", ... */
|
||||
UFUNCTION(BlueprintCallable, Category = "GigLine|Assets")
|
||||
static FString GetCollisionComplexity(UStaticMesh* Mesh);
|
||||
};
|
||||
@@ -134,7 +134,7 @@ void AGigLineCharacter::BeginPlay()
|
||||
{
|
||||
if (APlayerController* PC = Cast<APlayerController>(GetController()))
|
||||
{
|
||||
PC->ConsoleCommand(TEXT("HighResShot 1280 720"));
|
||||
PC->ConsoleCommand(TEXT("HighResShot 1280x720"));
|
||||
}
|
||||
}, 1.5f, false);
|
||||
|
||||
@@ -146,15 +146,26 @@ void AGigLineCharacter::BeginPlay()
|
||||
{
|
||||
UCharacterMovementComponent* M = GetCharacterMovement();
|
||||
UE_LOG(LogTemp, Log,
|
||||
TEXT("GigLine SIM: t=%.2f Z=%.0f grav=%.1f fall=%d local=%d role=%d mode=%d ctrl=%s"),
|
||||
TEXT("GigLine SIM: t=%.2f XYZ=(%.0f,%.0f,%.0f) grav=%.1f fall=%d local=%d role=%d mode=%d ctrl=%s"),
|
||||
GetWorld() ? GetWorld()->GetTimeSeconds() : -1.f,
|
||||
GetActorLocation().Z,
|
||||
GetActorLocation().X, GetActorLocation().Y, GetActorLocation().Z,
|
||||
M ? M->GetGravityZ() : 0.f,
|
||||
(M && M->IsFalling()) ? 1 : 0,
|
||||
IsLocallyControlled() ? 1 : 0,
|
||||
(int)GetLocalRole(),
|
||||
M ? (int)M->MovementMode : -1,
|
||||
GetController() ? *GetController()->GetName() : TEXT("NONE"));
|
||||
if (UWorld* W = GetWorld())
|
||||
{
|
||||
const FVector L = GetActorLocation();
|
||||
FHitResult Hit;
|
||||
FCollisionQueryParams Q(TEXT("GigLineGroundProbe"), false, this);
|
||||
const bool bHit = W->LineTraceSingleByChannel(Hit,
|
||||
FVector(L.X, L.Y, 3000.f), FVector(L.X, L.Y, -3000.f), ECC_Visibility, Q);
|
||||
UE_LOG(LogTemp, Log, TEXT("GigLine GROUND: top=%.0f actor=%s"),
|
||||
bHit ? Hit.ImpactPoint.Z : -9999.f,
|
||||
bHit && Hit.GetActor() ? *Hit.GetActor()->GetActorLabel() : TEXT("none"));
|
||||
}
|
||||
}, 1.0f, true);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user