fix(input): restore working controls + add input harness + build fixes

Consolidated from the qa-input-collision-fix-0.1.0 work, applied onto main so
only the changes main genuinely lacks are carried (main already merged the
walkable-demo/collision work independently).

- fix(input): populate the UE 5.8 FInputMappingContextMappingData
  DefaultKeyMappings field in ue_create_input_assets.py (the runtime reads
  GetMappings()->DefaultKeyMappings.Mappings; the script previously wrote only
  the deprecated 'mappings' array, so the cooked game had 0 runtime mappings
  and every key silently did nothing — in packaged AND PIE). Regenerated
  IMC_Default.uasset. WASD/mouse/Space/R/Escape verified working.
- fix(build): drop editor-only APIs that break the game target build —
  UStaticMesh::PostEditChange() (GigLineAssetTools) and AActor::GetActorLabel()
  (character ground probe). GigLine and GigLineEditor now both compile clean.
- tools: OS-level uinput input harness (input_emulation.py + input_test.py) and
  run_pie.sh for PIE isolation; document the PIE-vs-packaged input test in
  Docs/build.md. Removed the temporary SIM/EI/screenshot diagnostics from the
  character.
This commit is contained in:
zwitschi committed 2026-11-08 13:43:33 +01:00
1 parent 6b4e1252c5
commit 4832e66c00
8 files changed
+639 -56

No files matched your search

Binary file not shown.
@@ -21,7 +21,9 @@ void UGigLineAssetTools::SetComplexCollisionAsSimple(UStaticMesh* Mesh, bool bEn
BodySetup->InvalidatePhysicsData();
BodySetup->CreatePhysicsMeshes();
Mesh->MarkPackageDirty();
Mesh->PostEditChange();
// PostEditChange() is editor-only and not a member of UStaticMesh; the
// physics data regeneration above plus MarkPackageDirty is all a headless
// commandlet needs to persist the new collision flags.
}
void UGigLineAssetTools::ClearSimpleCollision(UStaticMesh* Mesh)
@@ -41,7 +43,6 @@ void UGigLineAssetTools::ClearSimpleCollision(UStaticMesh* Mesh)
BodySetup->InvalidatePhysicsData();
BodySetup->CreatePhysicsMeshes();
Mesh->MarkPackageDirty();
Mesh->PostEditChange();
}
FString UGigLineAssetTools::GetCollisionComplexity(UStaticMesh* Mesh)
@@ -157,46 +157,6 @@ void AGigLineCharacter::BeginPlay()
PC->bShowMouseCursor = false;
}
// TEMP QA: one screenshot at +1.5s so the actual frame is reviewable.
FTimerHandle ShotHandle;
GetWorldTimerManager().SetTimer(ShotHandle, [this]()
{
if (APlayerController* PC = Cast<APlayerController>(GetController()))
{
PC->ConsoleCommand(TEXT("HighResShot 1280x720"));
}
}, 1.5f, false);
// TEMP QA: every second log world time + capsule Z + gravity + fall state so
// we can see whether the world is simulating the pawn at all (symptom:
// "spawns above ground but never falls, no input").
FTimerHandle SimHandle;
GetWorldTimerManager().SetTimer(SimHandle, [this]()
{
UCharacterMovementComponent* M = GetCharacterMovement();
UE_LOG(LogTemp, Log,
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().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);
if (FParse::Param(FCommandLine::Get(), TEXT("qaselftest")))
{
StartQASelfTest();
@@ -428,8 +388,6 @@ namespace
void AGigLineCharacter::MoveForward(const FInputActionValue& Value)
{
UE_LOG(LogTemp, Log, TEXT("GigLine IN: MoveForward fired, axis=%.3f type=%d"),
FMath::Abs(SignedAxis(Value, false)), (int)Value.GetValueType());
ApplyMove(FMath::Abs(SignedAxis(Value, false)), 0.0f);
}
@@ -453,8 +411,6 @@ void AGigLineCharacter::ApplyMove(float Forward, float Strafe)
const AController* Controller = GetController();
if (!Controller)
{
UE_LOG(LogTemp, Log, TEXT("GigLine IN: ApplyMove called but NO controller (fwd %.2f strafe %.2f)"),
Forward, Strafe);
return;
}
if (FMath::IsNearlyZero(Forward) && FMath::IsNearlyZero(Strafe))
@@ -468,8 +424,6 @@ void AGigLineCharacter::ApplyMove(float Forward, float Strafe)
AddMovementInput(ForwardDir, Forward);
AddMovementInput(RightDir, Strafe);
UE_LOG(LogTemp, Log, TEXT("GigLine IN: ApplyMove fwd %.2f strafe %.2f controller=%s yaw=%.0f"),
Forward, Strafe, *Controller->GetName(), Controller->GetControlRotation().Yaw);
}
void AGigLineCharacter::Look(const FInputActionValue& Value)