5.5 Crash when rendering debug skeletal meshes

I’m updating my plugin from 5.4 to 5.5. Currently, other than some config issues, there have been no changes required. I experience a crash by hitting an assertion/check when loading a metahuman blueprint file.

My plugin creates an asset editor window and a persona preview scene. I then add either a single skeletal mesh or all skeletal meshes from a blueprint, to the preview scene as UDebugSkelMeshComponent. This is required as they have access to the preview instance to allow bone transform modifications.

When loading up a single mesh, everything is fine, however loading a metahuman blueprint, I experience a crash. This issue only happens if the face or torso/shirt mesh are included in my list. If both of these are excluded, or either are included by themselves, they work properly.

The crash appears to be an array out of bounds error from FBitReference operator(int32 Index). In debug mode, the index is always within the array limits, whilst still hitting the exception. This is called from SkeletalDebugRendering.cpp. This file does not appear to have been used when running my 5.4 plugin.

SkeletalDebugRendering is called from within FAnimationViewportClient::Draw(const FSceneView* View, FPrimitiveDrawInterface* PDI) which also doesn’t appear to be hit in 5.4. This function has a call to UpdateBonesToDraw() which uses the single (main?) preview mesh to get the required bones. These required bones are then used for all preview (debug) meshes in the scene.

I’m wondering if there is a bug here, where the required bones should be updated for each preview mesh? Alternatively, is there something that I’m doing wrong?

I’ve performed some more investigation here and found a few issues with my initial post.

In 5.4, I did not have Debugging Symbols enabled. This prevented my breakpoints from being hit, which I incorrectly assumed that the code was not being executed. Both the FAnimationViewportClient and SkeletalDebugRendering functions are being touched in 5.4 and 5.5.

With this, I believe that there is a bug regarding SkeletalDebugRendering::DrawBonesInternal() and FAnimationViewportClient::Draw() functions. The viewport class calls UpdateBonesToDraw() which calculates the BonesToDraw variable for the main Preview Mesh component from the scene. It’s Draw() function however, iterates through all Preview Meshes in the scene. This calls FAnimationViewportClient::DrawBones() for each mesh, which internally calls SkeletalDebugRendering::DrawBones(), however it uses the RequiredBones from the current mesh, but the BonesToDraw of the main mesh. This results in the SkeletalDebugRendering::DrawBonesInternal() call to hit an assertion.

I believe if BonesToDraw, which is an optional argument, was not passed here that the SkeletalDebugRendering would correctly calculate the BonesToDraw value internally. Alternatively, the viewport could update BonesToDraw based on the mesh it is currently processing. Either would fix the problem.