Character mesh gets offset after exiting crouch

I’m generating a character’s capsule collision and radius from the mesh at BeginPlay(). I can walk around fine using the associated animations as well as crouch, but it looks like my characters crouch height pops the mesh upward, and when the character stands up after the mesh is floating above the ground.

I’m not sure exactly what I’m getting wrong, whether there’s an issue with how I’m generating the collision, the halfHeight or if I need to augment the crouch() and uncrouch() functions with custom code. It seems to be related to the halfHeight getting overwritten because the debug output I have shows it matching my original value of 90 and then after uncrouch() goes back to the default of 88.



    /* Create Capsule Collision */
    if (GetMesh() && GetMesh()->SkeletalMesh != nullptr)
    {
        // Find this character's mesh bounds and scale.
        const FBoxSphereBounds MeshBounds{ GetMesh()->SkeletalMesh->GetBounds() };
        const FVector Scale3D{ GetMesh()->RelativeScale3D };

        // set collision cylinder appropriately to mesh size
        newRadius = { ((MeshBounds.BoxExtent.X + MeshBounds.BoxExtent.Y) / 2.0f) * 0.5f * FMath::Max(Scale3D.X, Scale3D.Y) };
        newHalfHeight = { MeshBounds.BoxExtent.Z * Scale3D.Z };

        // set the currently in-use cylinders
        GetCapsuleComponent()->SetCapsuleSize(newRadius, newHalfHeight);
        GetCapsuleComponent()->SetCapsuleHalfHeight(newHalfHeight);
        GetCapsuleComponent()->SetRelativeScale3D(FVector(1.0f, 1.0f, 1.0f));

        // Set Character Half Height for crouching
        GetCharacterMovement()->CrouchedHalfHeight = newHalfHeight;

        // Update the Mesh's relative location, taking into account foot-origin vs. center-origin characters.
        FVector NewRelativeLocation{ GetClass()->GetDefaultObject<AMWCharacterBase>()->GetMesh()->RelativeLocation };
        NewRelativeLocation.Z = -(GetCapsuleComponent()->GetScaledCapsuleHalfHeight());
        GetMesh()->SetRelativeLocation(NewRelativeLocation);

        UE_LOG(LogTemp, Warning, TEXT("Capsule Half Height %f"), GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight());
        UE_LOG(LogTemp, Warning, TEXT("Capsule Radius %f"), GetCapsuleComponent()->GetUnscaledCapsuleRadius());
        UE_LOG(LogTemp, Warning, TEXT("Character CrouchedHalfHeight %f"), GetCharacterMovement()->CrouchedHalfHeight);
    }


Here’s what the logs print out



LogTemp: Warning: Capsule Half Height 90.046127
LogTemp: Warning: Capsule Radius 28.170179
LogTemp: Warning: Character CrouchedHalfHeight 90.046127


Before first crouch. As you can see the character is standing on the floor and is comfortably within the ceiling of the frame.

First crouch, I noticed that the capsule collision isn’t getting resized, I presumed the crouch() function would do this, so perhaps it’s an issue with my setup.

Standing after first crouch

2nd Crouch

As a test I removed my capsule code posted above to see what things look like without. The capsule and character start in the same way that things end up in my prior post, with the character floating and the collision ill-fitting. However one key difference is that the collision does shrink when crouching, so I now understand that whatever I did looks to have broken that part.

The hunt continues.

p.s. If anyone can recommend a good tutorial or post to follow that helps with doing this sort of stuff that would be great to know. I’ve followed some online courses already, but they’ve all dealt with using out of the box Unreal guy with the starter animations so haven’t really touched upon working with different sized characters.

I delved deeper into the ACharacter.cpp and believe I’ve figured out a path through this now. Once I’ve cycled through the code a few times to resolve some of the issues I’m still seeing I’ll post my findings.

I’m still not clear on why the default halfHeight and radius are not being overwritten, but that’s not causing my any issues.

The issue of why the collision wasn’t shrinking when crouching was due to:



GetCharacterMovement()->CrouchedHalfHeight = newHalfHeight; 

Should be something more like the following to actually define the smaller capsule size for when crouching as it was setting both standing and crouching to the same height.


  
GetCharacterMovement()->CrouchedHalfHeight = newHalfHeight / 2;