DestructibleComponent does not respect calls to UPrimitiveComponent::SetCollisionEnabled or AActor::SetActorEnableCollision at runtime

Hello,

I am encountering the following issue:

  1. Create an actor with a DestructibleComponent and place it in the level
  2. In the level blueprint, implement a script (BeginPlay) → (Delay 0.5s) → (actor->SetActorEnableCollision false)
  3. Attempt to walk into the actor. Note it still has collision
  4. Replace the call to SetActorEnableCollision to (component->SetCollisionEnabled NoCollision)
  5. Attempt to walk into the actor. Note it still has collision

Expected result: at steps 3 and 5, the actor should not have collision

Note: The delay is not necessary for the repro, it just simulates behaviour that we want to trigger during gameplay.

This bug is because the two functions used access UPrimitiveComponent::BodyInstance directly, but for DestructibleComponents, this variable is unused. Instead, either the two functions should call GetBodyInstance(). I posted about this discrepancy before: why is there a virtual GetBodyInstance() function that isn’t called by most functions in PrimitiveComponentPhysics.cpp?

https://udn.unrealengine.com/questions/217333/uworldcomponentsweepmulti-and-similar-functions-ca.html

Regarding SetActorEnableCollision, the bug is due to this function:

void UPrimitiveComponent::OnActorEnableCollisionChanged()
{
	BodyInstance.UpdatePhysicsFilterData();
	OnComponentCollisionSettingsChanged();
}

The BodyInstance is not a valid body, so nothing happens. UDestructibleComponent should probably override OnActorEnableCollisionChanged and iterate over all it’s BodyInstances.

Regarding SetCollisionEnabled, the bug is due to this function:

void UPrimitiveComponent::SetCollisionEnabled(ECollisionEnabled::Type NewType)
{
	if (BodyInstance.GetCollisionEnabled() != NewType)
	{
		BodyInstance.SetCollisionEnabled(NewType);

		EnsurePhysicsStateCreated();
		OnComponentCollisionSettingsChanged();

	}
}

Again, BodyInstance is not a valid body, so nothing happens. UDestructibleComponent should probably override this function in a way similar to USkeletalMeshComponent::SetCollisionEnabled.

Thanks,
Isaac

Hey eyesiah-

I have reproduced the behavior on my end and have entered a bug report (UE-24868) for investigation. For now, you can use the following as a workaround. If you add a static mesh to the blueprint with the destructible mesh and set the static mesh to the same mesh as the DM, both the static mesh and DM will have their collision disabled.

Cheers

Doug Wilson

Hi Doug,
Thanks for the suggestion. The workaround I went for instead was to derive a new class from DestructibleComponent and override the functions as suggested in my original post, and use that new class in my blueprints instead.

Thanks again,
Isaac

link text

for future reference, I’ve attached a file containing the overridden functions that fixed the issue.