Hello,
I am encountering the following issue:
- Create an actor with a DestructibleComponent and place it in the level
- In the level blueprint, implement a script (BeginPlay) → (Delay 0.5s) → (actor->SetActorEnableCollision false)
- Attempt to walk into the actor. Note it still has collision
- Replace the call to SetActorEnableCollision to (component->SetCollisionEnabled NoCollision)
- 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?
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,