So, should RuntimeCellTransformerISM also have some corresponding handling for this case?
This would prevent rendering issues when Used with ISM has not been manually enabled, by relying on the Auto functionality to enable it automatically so that the material can render correctly.
In some relatively large projects, many materials do not have Used with ISM enabled. After those actors are processed by the transformer, their materials can end up missing.
The automatic assignment of the material usage cannot work in the context of the RuntimeCellTransformers for 2 reasons. The first reason is that the assignment is processing in UMaterial::SetMaterialUsage and this method is not called by the RCT ISM. The second reason is that the material usage flag cannot be changed in PIE which is the case when the RCTs are executed.
That being said, adding the call to SetMaterialUsage would work in the case of cooking. That would emit a warning about the missing flag but the cooked data would use the right material. You can use the following workaround:
void FISMComponentDescriptor::InitComponent(UInstancedStaticMeshComponent* ISMComponent) const
{
ISMComponent->SetStaticMesh(StaticMesh);
auto GetMaterial = [ISMComponent](UMaterialInterface* MaterialInterface)
{
if (MaterialInterface && !MaterialInterface->IsAsset())
{
// If the material is equivalent to its parent, just take a reference to its parent rather than making another redundant object
if (UMaterialInstance* Instance = Cast<UMaterialInstance>(MaterialInterface); Instance && Instance->IsRedundant())
{
MaterialInterface = Instance->Parent;
}
else
{
// As override materials are normally outered to their owner component, we need to duplicate them here to make sure we don't create
// references to actors in other levels (for packed level instances or HLOD actors).
MaterialInterface = DuplicateMaterialInterface(*MaterialInterface, *ISMComponent);
// If the MID we just duplicated has a nanite override that's also not an asset, duplicate that too
UMaterialInstanceDynamic* OverrideMID = Cast<UMaterialInstanceDynamic>(MaterialInterface);
UMaterialInterface* NaniteOverride = OverrideMID ? OverrideMID->GetNaniteOverride() : nullptr;
if (NaniteOverride && !NaniteOverride->IsAsset())
{
OverrideMID->SetNaniteOverride(DuplicateMaterialInterface(*NaniteOverride, *ISMComponent));
}
}
}
*** //Set the material usage for ISM. This only works in the context of cooking as SetMaterialUsage is not working in PIE.
*** if (MaterialInterface)
*** {
*** MaterialInterface->SetMaterialUsage(EMaterialUsage::MATUSAGE_InstancedStaticMeshes);
*** }
return MaterialInterface;
};