I’m seeing a problem where my Character collides with a “chain” in my level and an impulse is incorrectly being applied to the root body of the chain’s Skeletal Mesh Component. The Character’s collision object is a Capsule. The chain is an Actor with a Skeletal Mesh Component (SMC) consisting of about 10 bones/physics bodies. The physics bodies are connected with constraints. A few bodies near (and including) the root are set to “Kinematic” and thus should not move. The remaining bodies are set to “Simulate”. The motion of the chain before, during, and after collision appears to be essentially correct, However I keep getting the following Warning “spam”:
Warning: BP_GEN_MetalChain03TSH_2.SkeletalMesh SK_GEN_MetalChain01 has to have ‘Simulate Physics’ enabled if you’d like to AddImpulse.
Digging in with the debugger and source code in UPrimitiveComponent::UpdateOverlapsImpl method:
UPrimitiveComponent::UpdateOverlapsImpl is entered with 1 item on the NewPendingOverlaps list
“This” is the Character’s Collision Capsule (which is a UPrimitiveComponent).
The OverlapInfo for the item on the NewPendingOverlaps appears to be correct: bone name = Chain01_09 and Item = 4.
A few lines further into this method BeginComponentOverlap is called to dispatch “Begin Overlap” events to items on the NewPendingOverlaps list
My breakpoints and debug messages indicate that step 4 correctly results in an impulse being applied to the chain’s FBodyInstance corresponding to bone Chain01_09 , item 4.
The OverlappingComponents list now contains 1 item which corresponds to bone Chain01_09 , item 4, so appears this gets added to the “current” overlap list during the BeginComponentOverlap .
The next chunk of code calls into ComponentOverlapMulti and uses two lists, NewOverlappingComponentPtrs and OldOverlappingComponentPtrs in an attempt to identify and separate “New Overlaps” and “End Overlaps”.
Examining the Overlaps list returned by ComponentOverlapMulti I see it holds 1 FOverlapResult. Some of the overlap information looks correct (Actor and SkeletalMeshComponent match the chain), However the ItemIndex = -1. I think the ItemIndex=-1 is incorrect and is the root cause of this problem.
Next the HitResult data for the “ItemIndex=-1” is added to the NewOverlappingComponentPtrs list
Now the OldOverlappingComponentPtrs list is populated using the OverlappingComponents list, which contains our chain link item : bone Chain01_09 , item 4
If things were working correctly, I believe the data for bone Chain01_09 , item 4 would appear on BOTH lists above, instead of just on the OldOverlappingComponentPtrs list.
Next there’s a loop that attempts to separate the overlaps into two lists so the overlaps that are no longer present can have their “EndOverlap” events dispatched: “for (int32 CompIdx=0; CompIdx < OldOverlappingComponentPtrs.Num() && NewOverlappingComponentPtrs.Num() > 0; ++CompIdx) …”
After step 12 I see OldOverlappingComponentPtrs contains our chain link at item=4 , and the NewOverlappingComponentPtrs contains an overlap with item=-1 (invalid index).
The next chunk of code loops through OldOverlappingComponentPtrs and treats our new overlap at index 4 as though it were no longer overlapping, and INCORRECTLY dispatches an EndComponentOverlap to it.
The next chunk of code loops through NewOverlappingComponentPtrs and dispatches a “BeginOverlap” event with index = -1. The code responding to this event does not ignore it, but instead considers index=-1 (and bone name is None) to be applied to the root BodyInstance ! In our case the root BodyInstance is set to Kinematic so it does not move due to the AddImpulse, however I think if it were set to “Simulate” we would not receive a Warning but instead would see an impulse incorrectly applied to BodyInstance at root which was never collided with.
Is this a know bug ?
Is there some “checkbox” I am missing that would cause the ComponentOverlapMulti in step 8 to produce the correct results ?
Is there a “workaround” ?
Thanks in advance !