Heya, I’ve been trying to integrate recent GASP examples into our project and noticed a peculiar thing happening when a character crouches. I was able to reproduce this occurrence inside the GASP project as well.
I have attached 3 videos; in all of them, the Root `CapsuleComponent` has Pawn collisions enabled (the default value from GASP). But each has a different setting for the child `SkeletalMeshComponent`.
1st video - No Collision (NoCollision.mp4 attachment)
[Image Removed]
2nd video - Pawn preset (Pawn.mp4 attachment)
[Image Removed]
3rd video - Pawn preset, but Query only (QueryOnly.mp4 attachment)
[Image Removed]
When the SkeletalMesh has no collision whatsoever, the Capsule correctly stays above the terrain. But when the SkeletalMesh has collisions (even query/probe), the Capsule dips under the terrain and then jumps back up upon uncrouching.
[Image Removed]
Interestingly, it only happens when standing still and works correctly while moving.
In our project, we need the SkeletalMesh to have collision because of the combat system, so the NoCollision solution isn’t possible.
How should I go above fixing this issue to support SkeletalMesh having collisions while using your StanceModifier? Thanks!
Hello! Thanks for providing the videos. They were very helpful in reproducing the problem. I see that the issue occurs only during Crouch and Uncrouch transitions.
The problem occurs because:
during the uncrouch transition, FStanceModifier enqueues an instant teleportation effect to move the actor root upward to adjust for the change in capsule size
but that teleportation effect fails and has no effect due to the skeletal mesh having some intersection with the world.
Step by step, here is what happens. FStanceModifier::AdjustCapsule enqueues the teleport effect on crouch and uncrouch.
FTeleportEffect::ApplyMovementEffect calls the frankly, quite old school AActor::TeleportTo method. Note that the reasoning to use AActor::TeleportTo is because the DefaultMovementSet is meant to match CMC as closely as possible.
if (OwnerActor->TeleportTo(TargetLocation, FinalTargetRotation))This calls UWorld::EncroachingBlockingGeometry, which will test whether the actor would intersect anything at the new desired location. Here is where Mover will deviate from CMC:
If the actor has an UMovementComponent, which UMoverComponent is not, it will only check the primitive root
Since UMoverComponent is not, we fallback to checking collision for all components, including the skeletal mesh
EncroachingBlockingGeometry checks each component by testing whether anything in the world at the new location collides with the component’s Object Type. See: ComponentEncroachesBlockingGeometry_WithAdjustment.
I’ll raise this with the Mover devs to discuss whether we should (a) avoid calling AActor::TeleportTo to execute the teleport, or (b) update EncroachingBlockingGeometry to have a similar exception for Mover like in MovementComponent but that might be tricky/hacky seeing as Mover is an optional plugin. In the meantime, you can use the following workaround
Introduce a new object channel like (PawnTraceable, default: ignored) in your project settings
Assign the skeletal mesh the PawnTraceable. Since the new object channel is default ignored, existing world geo will ignore the skeletal mesh.
Update your game’s combat logic to trace/overlap/block the new object channel instead of the Pawn channel
Looking forward to hear the outcome of trying out the separate object channel!
After chatting internally with Mover devs, it seems the problem was already known as UE-308058. However, I filed a new bug UE-363516 with yours and my latest info. They will be addressed together. For Mover, we do want the option that some child components are tested for collision during teleports (including when crouching/uncrouching), but not for it to be the default.
Happy to help! I’ll close this question. If you periodically check up on the state of UE-363516, you’ll find out when we have addressed the bug internally.
Although, I suspect in general that the separate object channel will remain the cleanest way that ensures the skel mesh doesn’t affect anything that it shouldn’t.