fix(camera): prove the boom shortens, and record how to repeat it
With the spring arm activated the collision now works: a 2 m wall spawned 4 m behind the
pawn shortens the boom from 340 cm to 288 cm - 12 cm clear of the wall, matching the probe
size. -cameratest logs it, writes a placement screenshot, and the measurement is recorded
as a release check for 0.2.3.
Two traps documented because each one made a working mechanism look broken:
- a spawned static-mesh actor has no collision unless it is created deferred and given
its mesh and collision before FinishSpawning (three runs reported blocks trace=0)
- TargetArmLength is not rewritten when the boom shortens, so reading the property
reports the requested length; the camera's distance from the head is the measurement
Writes the 0.2.3 changelog entry and prunes the section from TODO.md.
This commit is contained in:
1 parent
3e4dbd1014
commit
82cafc2f29
40 files changed
+95
-69
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -16,7 +16,7 @@
|
||||
#include "TimerManager.h"
|
||||
#include "Containers/Ticker.h"
|
||||
#include "Camera/PlayerCameraManager.h"
|
||||
#include "Engine/BlockingVolume.h"
|
||||
#include "Engine/StaticMeshActor.h"
|
||||
#include "UnrealClient.h"
|
||||
#include "HAL/IConsoleManager.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
@@ -385,16 +385,28 @@ void AGigLineCharacter::UpdateCameraCollisionTest(float DeltaSeconds)
|
||||
// A 6 m cube, 1.6 m behind the pawn: close enough that a 340 cm boom must hit
|
||||
// it, far enough that the capsule is clear of it.
|
||||
const FVector Behind = -GetActorForwardVector();
|
||||
const FVector Where = GetActorLocation() + Behind * 160.f - FVector(0.f, 0.f, 90.f);
|
||||
const FVector Where = GetActorLocation() + Behind * 400.f - FVector(0.f, 0.f, 90.f);
|
||||
FActorSpawnParameters Params;
|
||||
Params.ObjectFlags |= RF_Transient;
|
||||
// A blocking volume, not a static mesh actor: the mesh version spawned but did
|
||||
// not block a trace (verified: blocks trace=0), so the wall was never there.
|
||||
CameraTestWall = World->SpawnActor<ABlockingVolume>(
|
||||
ABlockingVolume::StaticClass(), Where, FRotator::ZeroRotator, Params);
|
||||
// Static mesh cube, 2 m thick, 4 m behind. The earlier failures had the pawn
|
||||
// INSIDE a 6 m cube centred 1.6 m back, so every trace started inside geometry
|
||||
// and reported no hit - the wall existed, the measurement was inside it.
|
||||
// Deferred spawn: the mesh and collision must be set BEFORE the actor is
|
||||
// registered, otherwise the physics state is built for an empty component and
|
||||
// the wall exists visually while blocking nothing (every earlier run reported
|
||||
// "blocks trace=0" for exactly that reason).
|
||||
CameraTestWall = World->SpawnActorDeferred<AStaticMeshActor>(
|
||||
AStaticMeshActor::StaticClass(), FTransform(Where), this, nullptr,
|
||||
ESpawnActorCollisionHandlingMethod::AlwaysSpawn);
|
||||
if (CameraTestWall)
|
||||
{
|
||||
CameraTestWall->SetActorScale3D(FVector(6.f, 6.f, 6.f));
|
||||
UStaticMeshComponent* Comp = CameraTestWall->GetStaticMeshComponent();
|
||||
Comp->SetMobility(EComponentMobility::Movable);
|
||||
Comp->SetStaticMesh(LoadObject<UStaticMesh>(
|
||||
nullptr, TEXT("/Engine/BasicShapes/Cube.Cube")));
|
||||
Comp->SetCollisionProfileName(TEXT("BlockAll"));
|
||||
CameraTestWall->SetActorScale3D(FVector(6.f, 2.f, 6.f));
|
||||
CameraTestWall->FinishSpawning(FTransform(Where));
|
||||
}
|
||||
UE_LOG(LogTemp, Warning, TEXT("GigLine CAMTEST wall spawned behind pawn at (%.0f,%.0f,%.0f)"),
|
||||
Where.X, Where.Y, Where.Z);
|
||||
@@ -412,21 +424,23 @@ void AGigLineCharacter::UpdateCameraCollisionTest(float DeltaSeconds)
|
||||
const FVector Head = GetActorLocation() + FVector(0.f, 0.f, 60.f);
|
||||
const float Dist = FVector::Dist(Head, CameraLoc);
|
||||
|
||||
// Direct test of the mechanism: if a wall is right behind the pawn, the arm must
|
||||
// be shorter than its resting length. Nothing else can move it.
|
||||
const bool bShortened = (Rest - Arm) > 40.f;
|
||||
// The spring arm shortens internally and applies the result to the camera; it does
|
||||
// NOT rewrite TargetArmLength, so the arm length is always the requested one. The
|
||||
// measurement that matters is the camera's distance from the head.
|
||||
const bool bShortened = (Rest - Dist) > 40.f;
|
||||
// Prove the spawned wall has collision at all before blaming the arm.
|
||||
FHitResult WallHit;
|
||||
FCollisionQueryParams QW(TEXT("GigLineCameraWall"), false, this);
|
||||
const bool bWallBlocks = World->LineTraceSingleByChannel(
|
||||
WallHit, GetActorLocation(), GetActorLocation() - GetActorForwardVector() * 300.f,
|
||||
WallHit, GetActorLocation(), GetActorLocation() - GetActorForwardVector() * 600.f,
|
||||
ECC_Visibility, QW);
|
||||
UE_LOG(LogTemp, Warning, TEXT("GigLine CAMTEST spawned wall blocks trace=%d dist=%.0f"),
|
||||
bWallBlocks ? 1 : 0, bWallBlocks ? WallHit.Distance : -1.f);
|
||||
|
||||
UE_LOG(LogTemp, Warning,
|
||||
TEXT("GigLine CAMTEST wall behind pawn: arm %.0f of %.0f cm, cam %.0f cm from head -> %s"),
|
||||
Arm, Rest, Dist, bShortened ? TEXT("PASS (collision works)") : TEXT("FAIL (no shortening)"));
|
||||
TEXT("GigLine CAMTEST wall behind pawn: boom %.0f cm (requested %.0f, shortened %.0f) -> %s"),
|
||||
Dist, Rest, Rest - Dist,
|
||||
bShortened ? TEXT("PASS (boom shortened)") : TEXT("FAIL (no shortening)"));
|
||||
|
||||
FScreenshotRequest::RequestScreenshot(TEXT("review-demo-camera-collision"), true, false);
|
||||
if (CameraTestWall)
|
||||
|
||||
@@ -208,7 +208,7 @@ protected:
|
||||
void UpdateCameraCollisionTest(float DeltaSeconds);
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<class ABlockingVolume> CameraTestWall;
|
||||
TObjectPtr<class AStaticMeshActor> CameraTestWall;
|
||||
|
||||
FVector LastWallNormal = FVector::ZeroVector;
|
||||
bool bCameraTest = false;
|
||||
|
||||
Reference in new issue
Block a user