Use CameraComponent for view point and gaze target (VR/FPS compatibility)
- InteractionComponent: GetPawnViewPoint() now prefers UCameraComponent over PlayerController::GetPlayerViewPoint() — fixes agent selection in VR where the pawn root stays at spawn while the HMD moves freely - GazeComponent: ResolveTargetPosition() uses camera first for locally controlled pawns (VR HMD / FPS eye position), falls back to bone chain for NPCs and remote players in multiplayer Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e5f40c65ec
commit
8ad66ae4d5
@ -58,25 +58,41 @@ static FVector ResolveTargetPosition(const AActor* Target, bool bAutoEyes,
|
||||
{
|
||||
if (!Target) return FVector::ZeroVector;
|
||||
|
||||
if (bAutoEyes)
|
||||
if (!bAutoEyes)
|
||||
{
|
||||
// Try to find a Face mesh with eye bones on the target
|
||||
// Manual mode: actor origin + user-defined offset
|
||||
return Target->GetActorLocation() + ManualOffset;
|
||||
}
|
||||
|
||||
// For locally controlled pawns (VR/FPS player), prefer the CameraComponent.
|
||||
// In VR the pawn's skeletal mesh may stay at the spawn point while the HMD
|
||||
// moves freely — using eye bones would make the agent look at the floor.
|
||||
if (const APawn* Pawn = Cast<APawn>(Target))
|
||||
{
|
||||
if (Pawn->IsLocallyControlled())
|
||||
{
|
||||
if (const UCameraComponent* Cam =
|
||||
const_cast<AActor*>(Target)->FindComponentByClass<UCameraComponent>())
|
||||
{
|
||||
return Cam->GetComponentLocation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For other targets (NPCs, remote players): bone chain.
|
||||
TArray<USkeletalMeshComponent*> SkelMeshes;
|
||||
const_cast<AActor*>(Target)->GetComponents<USkeletalMeshComponent>(SkelMeshes);
|
||||
|
||||
for (const USkeletalMeshComponent* SMC : SkelMeshes)
|
||||
{
|
||||
if (!SMC) continue;
|
||||
|
||||
if (SMC->DoesSocketExist(TargetEyeBoneL) && SMC->DoesSocketExist(TargetEyeBoneR))
|
||||
{
|
||||
// Midpoint between both eye bones
|
||||
return (SMC->GetSocketLocation(TargetEyeBoneL)
|
||||
+ SMC->GetSocketLocation(TargetEyeBoneR)) * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: head bone on any mesh
|
||||
for (const USkeletalMeshComponent* SMC : SkelMeshes)
|
||||
{
|
||||
if (!SMC) continue;
|
||||
@ -86,20 +102,15 @@ static FVector ResolveTargetPosition(const AActor* Target, bool bAutoEyes,
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: CameraComponent — the canonical eye position for
|
||||
// first-person pawns and any actor with an active camera.
|
||||
// CameraComponent fallback for non-locally-controlled targets that have one.
|
||||
if (const UCameraComponent* Cam =
|
||||
const_cast<AActor*>(Target)->FindComponentByClass<UCameraComponent>())
|
||||
{
|
||||
return Cam->GetComponentLocation();
|
||||
}
|
||||
|
||||
// Final fallback: actor origin + height offset
|
||||
// Final fallback: actor origin + height offset.
|
||||
return Target->GetActorLocation() + FVector(0.0f, 0.0f, FallbackHeight);
|
||||
}
|
||||
|
||||
// Manual mode: actor origin + user-defined offset
|
||||
return Target->GetActorLocation() + ManualOffset;
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include "GameFramework/Pawn.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "Camera/PlayerCameraManager.h"
|
||||
#include "Camera/CameraComponent.h"
|
||||
#include "TimerManager.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
|
||||
@ -434,7 +435,17 @@ void UPS_AI_ConvAgent_InteractionComponent::GetPawnViewPoint(FVector& OutLocatio
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to get the player controller's camera view (most accurate for first/third person).
|
||||
// Prefer the CameraComponent directly — most reliable for VR (HMD) and FPS (eye level).
|
||||
// In VR the pawn's actor location stays at the spawn point while the HMD moves freely,
|
||||
// so GetPlayerViewPoint() may not reflect the actual head position.
|
||||
if (UCameraComponent* Cam = Owner->FindComponentByClass<UCameraComponent>())
|
||||
{
|
||||
OutLocation = Cam->GetComponentLocation();
|
||||
OutDirection = Cam->GetForwardVector();
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback: PlayerController view point (camera manager pipeline).
|
||||
if (APawn* Pawn = Cast<APawn>(Owner))
|
||||
{
|
||||
if (APlayerController* PC = Cast<APlayerController>(Pawn->GetController()))
|
||||
@ -446,7 +457,7 @@ void UPS_AI_ConvAgent_InteractionComponent::GetPawnViewPoint(FVector& OutLocatio
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: use actor location and forward.
|
||||
// Final fallback: actor transform.
|
||||
OutLocation = Owner->GetActorLocation();
|
||||
OutDirection = Owner->GetActorForwardVector();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user