GetCPUSkinnedVertices doesn't use morph targets like it promises. Am I missing something?

its a bug. in function USkinnedMeshComponent::GetCPUSkinnedVertices

// Recreate render state and flush the renderer
RecreateRenderState_Concurrent();

this would empty the active morph targets.

To slove this bug:

replace:

// Recreate render state and flush the renderer 
RecreateRenderState_Concurrent();

with:

// Recreate render state and flush the renderer 
// Cached the active morph targets, so that this function could work properly
TArray<FActiveMorphTarget> CachedActiveMorphTargets = ActiveMorphTargets;
TArray<float> CachedMorphTargetWeights = MorphTargetWeights;
if (bRenderStateCreated)
{
	check(IsRegistered()); // Should never have render state unless registered
	DestroyRenderState_Concurrent();
	checkf(!bRenderStateCreated, TEXT("Failed to route DestroyRenderState_Concurrent (%s)"), *GetFullName());
}

if (IsRegistered() && GetWorld()->Scene)
{
	ActiveMorphTargets = CachedActiveMorphTargets;
	MorphTargetWeights = CachedMorphTargetWeights;
	CreateRenderState_Concurrent();
	checkf(bRenderStateCreated, TEXT("Failed to route CreateRenderState_Concurrent (%s)"), *GetFullName());
}

it works for me anyway.