Fix thread-safety crash in LipSync anim node: TMap race condition
GetCurrentBlendshapes() was copying CurrentBlendshapes on the anim worker thread while the game thread mutated it (TSet::UnhashElements crash). Use a snapshot pattern: game thread copies to ThreadSafeBlendshapes under FCriticalSection at end of TickComponent, anim node reads the snapshot. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8d4065944c
commit
ca10689bb6
@ -1109,6 +1109,12 @@ void UPS_AI_ConvAgent_LipSyncComponent::TickComponent(float DeltaTime, ELevelTic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Snapshot for thread-safe anim node read (GetCurrentBlendshapes)
|
||||||
|
{
|
||||||
|
FScopeLock Lock(&BlendshapeLock);
|
||||||
|
ThreadSafeBlendshapes = CurrentBlendshapes;
|
||||||
|
}
|
||||||
|
|
||||||
// Auto-apply morph targets if a target mesh is set
|
// Auto-apply morph targets if a target mesh is set
|
||||||
if (TargetMesh)
|
if (TargetMesh)
|
||||||
{
|
{
|
||||||
@ -1201,6 +1207,10 @@ void UPS_AI_ConvAgent_LipSyncComponent::ResetToNeutral()
|
|||||||
|
|
||||||
// Clear blendshapes so the mouth returns to fully neutral
|
// Clear blendshapes so the mouth returns to fully neutral
|
||||||
CurrentBlendshapes.Reset();
|
CurrentBlendshapes.Reset();
|
||||||
|
{
|
||||||
|
FScopeLock Lock(&BlendshapeLock);
|
||||||
|
ThreadSafeBlendshapes.Reset();
|
||||||
|
}
|
||||||
PreviousBlendshapes.Reset();
|
PreviousBlendshapes.Reset();
|
||||||
LastConsumedVisemes.Reset();
|
LastConsumedVisemes.Reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -170,9 +170,14 @@ public:
|
|||||||
UFUNCTION(BlueprintCallable, Category = "PS AI ConvAgent|LipSync")
|
UFUNCTION(BlueprintCallable, Category = "PS AI ConvAgent|LipSync")
|
||||||
TMap<FName, float> GetCurrentVisemes() const { return SmoothedVisemes; }
|
TMap<FName, float> GetCurrentVisemes() const { return SmoothedVisemes; }
|
||||||
|
|
||||||
/** Get current ARKit blendshape weights (MetaHuman compatible: jawOpen, mouthFunnel, mouthClose, etc.). */
|
/** Get current ARKit blendshape weights (MetaHuman compatible: jawOpen, mouthFunnel, mouthClose, etc.).
|
||||||
|
* Thread-safe: returns a snapshot updated each tick. Safe to call from anim worker threads. */
|
||||||
UFUNCTION(BlueprintCallable, Category = "PS AI ConvAgent|LipSync")
|
UFUNCTION(BlueprintCallable, Category = "PS AI ConvAgent|LipSync")
|
||||||
TMap<FName, float> GetCurrentBlendshapes() const { return CurrentBlendshapes; }
|
TMap<FName, float> GetCurrentBlendshapes() const
|
||||||
|
{
|
||||||
|
FScopeLock Lock(&BlendshapeLock);
|
||||||
|
return ThreadSafeBlendshapes;
|
||||||
|
}
|
||||||
|
|
||||||
/** True when the agent is currently producing speech audio.
|
/** True when the agent is currently producing speech audio.
|
||||||
* When false, lip sync releases mouth curves to let emotion curves through. */
|
* When false, lip sync releases mouth curves to let emotion curves through. */
|
||||||
@ -268,9 +273,14 @@ private:
|
|||||||
// Smoothed viseme weights (interpolated each tick, exposed via GetCurrentVisemes)
|
// Smoothed viseme weights (interpolated each tick, exposed via GetCurrentVisemes)
|
||||||
TMap<FName, float> SmoothedVisemes;
|
TMap<FName, float> SmoothedVisemes;
|
||||||
|
|
||||||
// ARKit blendshape weights derived from SmoothedVisemes (exposed via GetCurrentBlendshapes)
|
// ARKit blendshape weights derived from SmoothedVisemes (game-thread working copy)
|
||||||
TMap<FName, float> CurrentBlendshapes;
|
TMap<FName, float> CurrentBlendshapes;
|
||||||
|
|
||||||
|
// Thread-safe snapshot of CurrentBlendshapes, updated each tick under BlendshapeLock.
|
||||||
|
// Read by the anim worker thread via GetCurrentBlendshapes().
|
||||||
|
TMap<FName, float> ThreadSafeBlendshapes;
|
||||||
|
mutable FCriticalSection BlendshapeLock;
|
||||||
|
|
||||||
// Previous frame's blendshape values for additional output smoothing
|
// Previous frame's blendshape values for additional output smoothing
|
||||||
TMap<FName, float> PreviousBlendshapes;
|
TMap<FName, float> PreviousBlendshapes;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user