check(!IsAsyncCreatePhysicsStateRunning()) inside UActorComponent::RecreatePhysicsState() does not seem necessary and results in a crash. What is it preventing?

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 the help,

Matt

[Attachment Removed]

Hello [mention removed]​

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.

I look forward to hearing from you soon.

All the best,

[mention removed]​

[Attachment Removed]

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.

[Attachment Removed]

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.

Hope this helps!

Geoff

[Attachment Removed]

Hello [mention removed]​

I understand it’s not easy to reproduce, but the extra context you shared will surely be useful! Thanks.

All the best,

[mention removed]​

[Attachment Removed]

Hello [mention removed]​

Sorry for the delayed response.

I’ve been trying to replicate the issue, but I was unable to cause that crash.

I’ll escalate to Epic, hoping they can reproduce and fix it quicker.

Thank you for your patience.

All the best,

[mention removed]​

[Attachment Removed]

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.

[Attachment Removed]