We are hitting an assertion in the editor when using [p.Chaos.EnableAsyncInitBody 1] because a sequencer is running on load and poking the collision of some meshes in the level that are async registering their physics.
The strange thing about this assert is that the code called in UActorComponent::DestroyPhysicsState following the assert handles the condition that its asserting:
void UActorComponent::RecreatePhysicsState()
{
TRACE_CPUPROFILER_EVENT_SCOPE(UActorComponent::RecreatePhysicsState);
check(!IsAsyncCreatePhysicsStateRunning());
DestroyPhysicsState();
if (IsRegistered())
{
CreatePhysicsState();
}
}
void UActorComponent::DestroyPhysicsState()
{
TRACE_CPUPROFILER_EVENT_SCOPE(UActorComponent::DestroyPhysicsState);
SCOPE_CYCLE_COUNTER(STAT_ComponentDestroyPhysicsState);
if (IsAsyncCreatePhysicsStateRunning())
{
check(!IsAsyncDestroyPhysicsStateRunning());
check(!IsA<UPrimitiveComponent>() || !Cast<UPrimitiveComponent>(this)->DeferredCreatePhysicsStateScene);
PhysicsStateAsyncCreationScene->RemoveAsyncPhysicsStateJobs(this);
// Reset members used by asynchronous physics state creation
bCallAsyncPhysicsStateCreatedDelegate = false;
PhysicsStateAsyncCreationState = EPhysicsStateAsyncCreationState::None;
PhysicsStateAsyncCreationScene = nullptr;
AActor* MyOwner = GetOwner();
if (ULevel* Level = MyOwner ? MyOwner->GetLevel() : nullptr)
{
FLevelRegistrationAccessor::OnRemovedPreRegisteringComponent(Level, this);
}
}
If you remove that assert, the game seems to continue fine, but you hit this verify(PreRegisteringActorComponents.Remove(Component)) in OnRemovedPreRegisteringComponent.
Is that assert actually stopping something bad? if not can it be safely removed or downgraded?
Thank you for reaching out and bringing this issue to our attention.
I’ve been trying to reproduce the described behavior in a repro project to share with the dev team, but I’m failing to reach the setup that triggers the crash.
Could you elaborate a bit more on the steps you followed to reach that state?
A minimal project that reproduces the issue also works.
It would not be easy to send you a repo connected to our game. The conditions that create this assert for us come from a sequencer toggling collision on an asset at the same time the tile is loading and registering physics. I think part the conditions is the throughput of how many assets are sitting in the async queue. This issue does not repo in a simple test level because there are not enough physics registrations.
Hi Matt, and apologies for the delay for the response.
In this case, the you are correct that DestroyPhysicsState itself handles the AyncCreate situation, but from the perspective of the RecreatePhysicsState function, it would then cause and issue in the IsRegistered check (which would fail) and then not run the CreatePhysicsState - ie the function would not work correctly and hence the check.
A repo would be nice, but someone should be able to look at the code and figure out if that assert is really needed. The code handles the condition of the assert right after it raises it, so either that assert is wrong or the code that follows it is wrong. There is a code bug here that needs to get sorted out.