Description

ChaosCacheManager is not properly recording the state of each particle when toggling Fields and Anchor Fields in the scene. During my investigations I've noticed that ChaosCacheManager does not record initialization fields, and I suspect this can be the root cause of the unexpected behavior described by the licensee.

The licensee has provided a repro project with a demo scene that displays the unexpected behavior. The demo scene is composed of a Geometry Collection (GC), two FS_AnchorFields (AF) that hold the GC in place at each side, and a FS_MasterField (MF) in the middle of the GC.

Setting ChaosCacheManager (CCM) to CacheMode - RECORD, and playing the scene in the editor (PIE), we verify that after 5 seconds the MF breaks the GC and the middle portion falls to the ground. After 10 seconds a timer (in each AF), spawns a MF in place of the AF and destroys itself. The MFs wake up the particles on each side of the remaining floating GC and make them fall as a single block. Once they hit the ground, they further fragment from the collision. If we stop PIE the session is recorded on the CCM.

Changing CCM to CacheMode - Play and PIE we see the reproduction of the recorded simulation and the unexpected behavior: the middle portion gets fragmented and it's a perfect reproduction, but the sides that originally fall as a block now fragment immediately in the air, some showing strange rotations like their pivots are not at their center, and they all fall down in slow motion.

I've profiled both behaviors using Chaos Visual Debugger. The simulation shows the animation of the falling particles in the Physics World Scene (PWS). The reproduction of the CCM, like expected, does not simulate the particles, so they vanish from the PWS. I would assume they would only show up at the end of the animation or not at all since they were controlled by the animator and not by physics simulation, but they show around the point where the AF are removed and the new MF are added (~10 second into the execution). They display the floating sides fragmented but still floating in the air, and a little later they fall down, animated by the gravity while some parts still remain floating.

I was suspicious that the removal of the AFs or the spawning of MF midway was responsible for breaking the recording, so I changed the setup to have all elements in the scene all the time without deletion, just disabling the AFs and enabling the MFs, but the behavior is the same.

While stepping thru the code I've found a possible culprit in UChaosCache::BuildSpawnableFromComponent():

// make sure we do not have any initialization fields because those may also keep dangling references preventing garbage collection
if (UGeometryCollectionComponent* GeometryCollectionComponent = Cast<UGeometryCollectionComponent>(Spawnable.DuplicatedTemplate))
{
GeometryCollectionComponent->InitializationFields.Empty();
}
Steps to Reproduce
  • Create a New Level using the Basic Template
  • Add a Cube blueprint to the level
  • Set scale to (2,10,2) and position it on the air, not touching the ground
  • Select it and activate Fracture Mode (SHIFT+6)
  • Press New - save the new GC preferably in your project folder
  • Select Fracture>Uniform
  • Press Fracture - that will split it in multiple fragments
  • Back to Selection Mode (SHIFT+1)
  • Search in the Content Browser (Show Engine Content enabled) for FS_MasterField (MF) - add one to the scene and position it around the middle of the GC
  • Search Content Browser for FS_AnchorField_Generic(AF) and Create Child Blueprint class (or duplicate it) into your project
  • Edit the Child/Duplicate of AF
  • On BeginPlay pull a Delay and after 5 seconds do a Destroy self, compile and save
  • Spawn two of that Child/Duplicate of AF and position so they hold the GC on the air by the sides
  • "Quickly add to the project" a ChaosCacheManager (CCM)
    In the Content Browser, create a ChaosCacheCollector, save, and drag it to the CCM
  • Put the CCM to CacheMode RECORD and press play in editor (PIE), wait for the simulation to end and stop (ESC) - the CCM will have the simulation recorded
  • Put the CCM to CacheMode Play and PIE - verify that the animation does not follow the simulation and some odd behavior is observable, like a low fall of the particles
Callstack

Non-fatal but this is the callstack of the potentially incorrect behavior:
> UnrealEditor-ChaosCaching.dll!UChaosCache::BuildSpawnableFromComponent(const UPrimitiveComponent * InComponent, const UE::Math::TTransform<double> & SpaceTransform) Line 750 C++
UnrealEditor-ChaosCaching.dll!UChaosCache::BeginRecord(const UPrimitiveComponent * InComponent, FGuid InAdapterId, const UE::Math::TTransform<double> & SpaceTransform) Line 416 C++
UnrealEditor-ChaosCaching.dll!AChaosCacheManager::BeginEvaluate() Line 498 C++
UnrealEditor-Engine.dll!AActor::DispatchBeginPlay(bool bFromLevelStreaming) Line 4193 C++
UnrealEditor-Engine.dll!AWorldSettings::NotifyBeginPlay() Line 305 C++
UnrealEditor-Engine.dll!AGameStateBase::HandleBeginPlay() Line 228 C++
UnrealEditor-Engine.dll!AGameModeBase::StartPlay() Line 206 C++
UnrealEditor-Engine.dll!UWorld::BeginPlay() Line 5330 C++
UnrealEditor-Engine.dll!UGameInstance::StartPlayInEditorGameInstance(ULocalPlayer * LocalPlayer, const FGameInstancePIEParameters & Params) Line 568 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::CreateInnerProcessPIEGameInstance(FRequestPlaySessionParams & InParams, const FGameInstancePIEParameters & InPIEParameters, int InPIEInstanceIndex) Line 3141 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::OnLoginPIEComplete_Deferred(int LocalUserNum, bool bWasSuccessful, FString ErrorString, FPieLoginStruct DataStruct) Line 1590 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::CreateNewPlayInEditorInstance(FRequestPlaySessionParams & InRequestParams, const bool bInDedicatedInstance, const EPlayNetMode InNetMode) Line 1853 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::StartPlayInEditorSession(FRequestPlaySessionParams & InRequestParams) Line 2872 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequestImpl() Line 1167 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::StartQueuedPlaySessionRequest() Line 1068 C++
UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1902 C++
UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 550 C++
UnrealEditor.exe!FEngineLoop::Tick() Line 5921 C++
[Inline Frame] UnrealEditor.exe!EngineTick() Line 61 C++
UnrealEditor.exe!GuardedMain(const wchar_t * CmdLine) Line 180 C++
UnrealEditor.exe!LaunchWindowsStartup(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow, const wchar_t * CmdLine) Line 247 C++
UnrealEditor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * pCmdLine, int nCmdShow) Line 298 C++
[External Code]

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-228459 in the post.

1
Login to Vote

Unresolved
ComponentUE - Simulation - Physics - Destruction
Affects Versions5.4.4
Target Fix5.6
CreatedOct 22, 2024
UpdatedOct 23, 2024
View Jira Issue