Mutable static mesh clips meshes and data tables throwing ensure

Howdy!

We are looking to leverage data tables in Mutable CO graphs to flexibly feed in our static mesh clip meshes.

When doing so, we hit an ensure in line 461 of GenerateMutableSource.cpp. Plugging in a hard reference to the static mesh clip mesh asset fixes the ensure, but since we will have a wide variety of outfits, we need to use something like a data table in order to feed in variable data.

What’s the correct approach here? Notably, if we use skeletal mesh assets instead of static mesh assets, the ensure no longer occurs. Should we not be using static meshes at all in this pipeline? Skinning them to the root is little overhead, so it’s not too concerning. Supporting static meshes would be rad.

Here is a repro as well:

1) Create a CO, a struct for static mesh clip meshes, and a data table based on the struct.

[Image Removed]

2) In the CO, use the clip mesh node and supply the data table field.

[Image Removed]

3) Compile the CO and you will hit the ensure.

Steps to Reproduce
1) Create a CO, a struct for static mesh clip meshes, and a data table based on the struct.

[Image Removed]

2) In the CO, use the clip mesh node and supply the data table field.

[Image Removed]

3) Compile the CO and you will hit the ensure.

Hey there,

I’m unable to repro your issue and hit the ensure. I don’t see a table node in your graph that you are exporting data to? Typically it would look something like.

[Image Removed]The top table node connects to an export mesh variable. Then, in the child object reference, I import the mesh pin node. If your setup matches, would you be able to share any files or a test graph with the callstack to the ensure you are hitting?

Thanks,

Dustin

I don’t think so. That is allowed, just fine. Do you have a default value for the static mesh in your struct?

Could you share the ensure with me? Callstack, log, or anything that indicates what the error might be pointing at?

Great, this is helpful. There have been some significant changes to the AddParticipatingObjects layer in Mutable for 5.6, where we moved it out and into a different pass. This is likely fixed there.

For 5.5, though, this is an indicator that the FGUID of the static mesh or table has changed between when the customizable object first ran the add participating objects and when it was compiled. So I’m likely not hitting the repro because of that ordering. If you close and unload the CO, then resave the data table and reopen and recompile, do you still encounter the issue? Is the repro consistent? Are there any details that you can add to your repro steps on how assets are created, opened, saved, or loaded that help pinpoint the timing of the issue? Do you get failures when building a mutable character with a static mesh at runtime, or is this an editor-only issue?

This is great, thank you.

Since you plan to upgrade to 5.6 soon, I’ll continue to attempt to reproduce the issue using more of this information and post back here later this week.

Dustin

That’s great to hear! I was unable to reproduce the issue and was chatting with the dev team about it, but we weren’t making traction.

Dustin

Oh, apologies! I neglected to include some important nodes.

[Image Removed]We ref’d the data table here and created the node variable for ClipMesh and SkelMesh.

[Image Removed]We fed those variables in here. The FStruct the table is based on is just a Skeletal Mesh and then Static Mesh entry.

Sorry for the confusion! It looks like that might be what you’re doing though. Is it because we have both a skel mesh and a static mesh in the table perhaps?

>	UnrealEditor-CustomizableObjectEditor.dll!FMutableGraphGenerationContext::AddParticipatingObjectChecked::__l10::<lambda_1>::operator()() Line 461	C++
 	[Inline Frame] UnrealEditor-CustomizableObjectEditor.dll!FMutableGraphGenerationContext::AddParticipatingObjectChecked(const FName &) Line 461	C++
 	UnrealEditor-CustomizableObjectEditor.dll!FMutableGraphGenerationContext::AddParticipatingObject(const FSoftObjectPath & SoftPath) Line 165	C++
 	UnrealEditor-CustomizableObjectEditor.dll!FillTableColumn(const UCustomizableObjectNodeTable * TableNode, mu::Ptr<mu::Table> MutableTable, const FString & ColumnName, const FString & RowName, unsigned int RowId, unsigned char * CellData, const FProperty * ColumnProperty, int LODIndexConnected, int SectionIndexConnected, int LODIndex, int SectionIndex, unsigned int SectionMetadataId, bool bOnlyConnectedLOD, FMutableGraphGenerationContext & GenerationContext) Line 338	C++
 	UnrealEditor-CustomizableObjectEditor.dll!GenerateTableColumn(const UCustomizableObjectNodeTable * TableNode, const UEdGraphPin * Pin, mu::Ptr<mu::Table> MutableTable, const FString & DataTableColumnName, const FProperty * ColumnProperty, int LODIndexConnected, int SectionIndexConnected, int LODIndex, int SectionIndex, unsigned int SectionMetadataId, bool bOnlyConnectedLOD, FMutableGraphGenerationContext & GenerationContext) Line 975	C++
 	UnrealEditor-CustomizableObjectEditor.dll!GenerateMutableSourceMesh(const UEdGraphPin * Pin, FMutableGraphGenerationContext & GenerationContext, FMutableGraphMeshGenerationData & MeshData, unsigned int SurfaceMetadataId, bool bLinkedToExtendMaterial, bool bOnlyConnectedLOD) Line 4258	C++
 	UnrealEditor-CustomizableObjectEditor.dll!GenerateMutableSourceModifier(const UEdGraphPin * Pin, FMutableGraphGenerationContext & GenerationContext) Line 171	C++
 	UnrealEditor-CustomizableObjectEditor.dll!GenerateMutableSource(const UEdGraphPin * Pin, FMutableGraphGenerationContext & GenerationContext) Line 980	C++
 	UnrealEditor-CustomizableObjectEditor.dll!GenerateMutableSource(const UEdGraphPin * Pin, FMutableGraphGenerationContext & GenerationContext) Line 1116	C++
 	UnrealEditor-CustomizableObjectEditor.dll!GenerateMutableSource(const UEdGraphPin * Pin, FMutableGraphGenerationContext & GenerationContext) Line 1031	C++
 	UnrealEditor-CustomizableObjectEditor.dll!GenerateMutableRoot(const UCustomizableObject * Object, FMutableGraphGenerationContext & GenerationContext) Line 621	C++
 	UnrealEditor-CustomizableObjectEditor.dll!FCustomizableObjectCompiler::CompileInternal(bool bAsync) Line 757	C++
 	UnrealEditor-CustomizableObjectEditor.dll!FCustomizableObjectCompiler::Compile(const TSharedRef<FCompilationRequest,1> & InCompileRequest) Line 304	C++
 	[Inline Frame] UnrealEditor-CustomizableObjectEditor.dll!FCustomizableObjectCompiler::TryPopCompileRequest() Line 1176	C++
 	UnrealEditor-CustomizableObjectEditor.dll!FCustomizableObjectCompiler::Tick(bool bBlocking) Line 53	C++
 	UnrealEditor-CustomizableObjectEditor.dll!FCustomizableObjectCompiler::Tick(float InDeltaTime) Line 325	C++
 	[Inline Frame] UnrealEditor-UnrealEd.dll!FTickableEditorObject::TickObjects::__l2::<lambda_1>::operator()(FTickableObjectBase * TickableObject) Line 33	C++
 	[Inline Frame] UnrealEditor-UnrealEd.dll!Invoke(FTickableEditorObject::TickObjects::__l2::<lambda_1> &) Line 47	C++
 	UnrealEditor-UnrealEd.dll!UE::Core::Private::Function::TFunctionRefCaller<`FTickableEditorObject::TickObjects'::`2'::<lambda_1>,void,FTickableObjectBase *>::Call(void * Obj, FTickableObjectBase * & <Params_0>) Line 315	C++
 	[Inline Frame] UnrealEditor-Engine.dll!UE::Core::Private::Function::TFunctionRefBase<UE::Core::Private::Function::FFunctionRefStoragePolicy,void __cdecl(FTickableObjectBase *)>::operator()(FTickableObjectBase * <Params_0>) Line 470	C++
 	UnrealEditor-Engine.dll!FTickableObjectBase::SimpleTickObjects(FTickableObjectBase::FTickableStatics & Statics, TFunctionRef<void __cdecl(FTickableObjectBase *)> TickFunc) Line 112	C++
 	[Inline Frame] UnrealEditor-UnrealEd.dll!FTickableEditorObject::TickObjects(const float) Line 30	C++
 	UnrealEditor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1898	C++
 	UnrealEditor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 550	C++

Here’s the call stack! We have one custom engine change in 5.5 in CustomizableObjectSystem.cpp. We changed:

if (ScalarName.ToString().Equals(EncodingMaterialIdString))to

if (ScalarName.ToString().Contains(EncodingMaterialIdString))Maybe it’s a knock off of this change we made since you aren’t seeing it. This change was to allow for Mutable to consume data tables with multiple materials (since we ran into issues with that functionality, but maybe we spawned a new issue here. Mutable would only “see” the 0 index material).

Hey Dustin!

Sorry for the very late reply on this. I do still hit the ensure then. I tried a few methods:

  • Close/unload the CO, resave the data table, reopen and recompile. Hit the ensure.
  • Unpinned the DT pins (removing the ensure), closed the CO, resaved the data table, reopened the CO + reconnected pins and recompiled. Hit the ensure.
  • Removed the DT reference, saved CO + closed, resaved the DT, reopened the CO + re-added DT reference and recompiled. Hit the ensure.

The repro is consistent each time. It happens only the first time I open the asset each editor session, but it happens each time I hit compile consistently. This appears to be an editor only issue. I can place the test skel mesh cube with its CO inst in a BP and load into the level without hitting an ensure.

The repro steps in 5.5 only required the following assets (BP / _Inst optional)

[Image Removed]CO graph is as follows

[Image Removed]DT is set up like so

[Image Removed]

Please let me know if there’s anything else I can provide!

We are upgrading to 5.6 next week, so I will also follow up on if that fixes it for us.

Hey Dustin,

Just to let you know, upgrading to 5.6 did resolve this. I no longer trigger the ensure with no changes to the previous set up.