Split posture: eyes+head on selection, body on conversation start
PostureComponent gains bEnableBodyTracking flag. When false, only head and eyes track the target — body stays frozen. InteractionComponent now: - On posture attach: sets TargetActor but disables body tracking (agent notices player with eyes+head only) - On StartListening: enables body tracking (agent fully engages) - On StopListening: disables body tracking Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
23e216b211
commit
92a8b70a7f
@ -198,6 +198,12 @@ void UPS_AI_ConvAgent_InteractionComponent::SetSelectedAgent(UPS_AI_ConvAgent_El
|
|||||||
if (bAutoManageListening)
|
if (bAutoManageListening)
|
||||||
{
|
{
|
||||||
OldAgent->StopListening();
|
OldAgent->StopListening();
|
||||||
|
|
||||||
|
// Disable body tracking — eyes+head will return to neutral via posture detach.
|
||||||
|
if (UPS_AI_ConvAgent_PostureComponent* Posture = FindPostureOnAgent(OldAgent))
|
||||||
|
{
|
||||||
|
Posture->bEnableBodyTracking = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Posture: detach ──────────────────────────────────────────────
|
// ── Posture: detach ──────────────────────────────────────────────
|
||||||
@ -244,6 +250,12 @@ void UPS_AI_ConvAgent_InteractionComponent::SetSelectedAgent(UPS_AI_ConvAgent_El
|
|||||||
if (bAutoManageListening)
|
if (bAutoManageListening)
|
||||||
{
|
{
|
||||||
NewAgent->StartListening();
|
NewAgent->StartListening();
|
||||||
|
|
||||||
|
// Now that we're talking, enable full body tracking.
|
||||||
|
if (UPS_AI_ConvAgent_PostureComponent* Posture = FindPostureOnAgent(NewAgent))
|
||||||
|
{
|
||||||
|
Posture->bEnableBodyTracking = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Posture: attach ──────────────────────────────────────────────
|
// ── Posture: attach ──────────────────────────────────────────────
|
||||||
@ -345,10 +357,12 @@ void UPS_AI_ConvAgent_InteractionComponent::AttachPostureTarget(
|
|||||||
if (UPS_AI_ConvAgent_PostureComponent* Posture = FindPostureOnAgent(AgentPtr))
|
if (UPS_AI_ConvAgent_PostureComponent* Posture = FindPostureOnAgent(AgentPtr))
|
||||||
{
|
{
|
||||||
Posture->TargetActor = GetOwner();
|
Posture->TargetActor = GetOwner();
|
||||||
|
// Eyes+head only at first — body tracking is enabled when listening starts.
|
||||||
|
Posture->bEnableBodyTracking = false;
|
||||||
|
|
||||||
if (bDebug)
|
if (bDebug)
|
||||||
{
|
{
|
||||||
UE_LOG(LogPS_AI_ConvAgent_Select, Log, TEXT("Posture attached: %s -> %s"),
|
UE_LOG(LogPS_AI_ConvAgent_Select, Log, TEXT("Posture attached (eyes+head only): %s -> %s"),
|
||||||
AgentPtr->GetOwner() ? *AgentPtr->GetOwner()->GetName() : TEXT("(null)"),
|
AgentPtr->GetOwner() ? *AgentPtr->GetOwner()->GetName() : TEXT("(null)"),
|
||||||
GetOwner() ? *GetOwner()->GetName() : TEXT("(null)"));
|
GetOwner() ? *GetOwner()->GetName() : TEXT("(null)"));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -240,12 +240,16 @@ void UPS_AI_ConvAgent_PostureComponent::TickComponent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Body smoothly interpolates toward its persistent target
|
// Body smoothly interpolates toward its persistent target
|
||||||
const float BodyDelta = FMath::FindDeltaAngleDegrees(
|
// (only when body tracking is enabled — otherwise only head+eyes move).
|
||||||
Owner->GetActorRotation().Yaw, TargetBodyWorldYaw);
|
if (bEnableBodyTracking)
|
||||||
if (FMath::Abs(BodyDelta) > 0.1f)
|
|
||||||
{
|
{
|
||||||
const float BodyStep = FMath::FInterpTo(0.0f, BodyDelta, SafeDeltaTime, BodyInterpSpeed);
|
const float BodyDelta = FMath::FindDeltaAngleDegrees(
|
||||||
Owner->AddActorWorldRotation(FRotator(0.0f, BodyStep, 0.0f));
|
Owner->GetActorRotation().Yaw, TargetBodyWorldYaw);
|
||||||
|
if (FMath::Abs(BodyDelta) > 0.1f)
|
||||||
|
{
|
||||||
|
const float BodyStep = FMath::FInterpTo(0.0f, BodyDelta, SafeDeltaTime, BodyInterpSpeed);
|
||||||
|
Owner->AddActorWorldRotation(FRotator(0.0f, BodyStep, 0.0f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 3. Compute DeltaYaw after body interp ──────────────────────────
|
// ── 3. Compute DeltaYaw after body interp ──────────────────────────
|
||||||
@ -274,7 +278,7 @@ void UPS_AI_ConvAgent_PostureComponent::TickComponent(
|
|||||||
BodyTargetFacing, TargetWorldYaw);
|
BodyTargetFacing, TargetWorldYaw);
|
||||||
|
|
||||||
bool bBodyOverflowed = false;
|
bool bBodyOverflowed = false;
|
||||||
if (FMath::Abs(DeltaFromBodyTarget) > MaxHeadYaw + MaxEyeHorizontal)
|
if (bEnableBodyTracking && FMath::Abs(DeltaFromBodyTarget) > MaxHeadYaw + MaxEyeHorizontal)
|
||||||
{
|
{
|
||||||
// Body realigns to face target
|
// Body realigns to face target
|
||||||
TargetBodyWorldYaw = TargetWorldYaw - MeshForwardYawOffset;
|
TargetBodyWorldYaw = TargetWorldYaw - MeshForwardYawOffset;
|
||||||
|
|||||||
@ -73,6 +73,12 @@ public:
|
|||||||
meta = (ToolTip = "Target actor to look at.\nSet to null to return to neutral."))
|
meta = (ToolTip = "Target actor to look at.\nSet to null to return to neutral."))
|
||||||
TObjectPtr<AActor> TargetActor;
|
TObjectPtr<AActor> TargetActor;
|
||||||
|
|
||||||
|
/** When false, body rotation is frozen — only head and eyes track the target.
|
||||||
|
* Useful to have the agent notice the player (eyes+head) before fully engaging (body). */
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS AI ConvAgent|Posture",
|
||||||
|
meta = (ToolTip = "Enable body rotation toward the target.\nWhen false, only head and eyes track."))
|
||||||
|
bool bEnableBodyTracking = true;
|
||||||
|
|
||||||
/** Offset from the target actor's origin to aim at.
|
/** Offset from the target actor's origin to aim at.
|
||||||
* Useful for actors without a skeleton (e.g. (0,0,160) for eye-level). */
|
* Useful for actors without a skeleton (e.g. (0,0,160) for eye-level). */
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS AI ConvAgent|Posture",
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS AI ConvAgent|Posture",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user