I am doing an Editor plugin who saves textures atlas, I want to save the atlas information on a MaterialParameterCollection, I save and its good;
the problem is when I like to update with new values the MaterialParameterCollection it breaks the Engine;
I wanna know what I need to do.
I actually have load the asset:
UMaterialParameterCollection* Collection;
UMaterialParameterCollectionInstance* Inst_Collection = GEditor->GetEditorWorldContext().World()->GetParameterCollectionInstance(Collection);
I made the changes actually: (I try the another methods but do faster break UE4)
//Inst_Collection->SetScalarParameterValue(NewCollection->ScalarParameters[newScalar].ParameterName, NewCollection->ScalarParameters[newScalar].DefaultValue);
//UKismetMaterialLibrary::SetScalarParameterValue(GEditor->GetEditorWorldContext().World(), Collection, NewCollection->ScalarParameters[newScalar].ParameterName, NewCollection->ScalarParameters[newScalar].DefaultValue);
Collection->ScalarParameters.Add(NewCollection->ScalarParameters[newScalar]);
Later I do this:
Inst_Collection->SetCollection(Collection, GEditor->GetEditorWorldContext().World());
Inst_Collection->PostLoad();
Inst_Collection->PostEditChangeProperty(PropertyChanged);
Later I do this:
Inst_Collection->SetCollection(Collection, GEditor->GetEditorWorldContext().World());
Inst_Collection->PostLoad();
Inst_Collection->PostEditChangeProperty(PropertyChanged);
The error actually is after the Material loses the Name of the MPC to “None” I can open the Material and the names of the MPC set down, but when I click Unreal breaks.
Assertion failed: UniformBufferStruct [File:D:\Build++UE4+Release-4.16+Compile\Sync\Engine\Source\Runtime\Engine\Classes\Materials/MaterialParameterCollection.h] [Line: 120]
One week of headaches, looking thought UE code I can make it after I change the scalar and Vector Parameters I do this:
I need to do an update on every world the MPC, and find every material who uses the MPC to update it:
At the moment I lose the parameter name but in the future, I will look for fix that.
Collection->PostLoad();
Collection->PostEditChange();
for (TObjectIterator<UWorld> It; It; ++It)
{
UWorld* CurrentWorld = *It;
CurrentWorld->AddParameterCollectionInstance(Collection, true);
CurrentWorld->SetupParameterCollectionInstances();
CurrentWorld->UpdateParameterCollectionInstances(true);
//CurrentWorld->GetParameterCollectionInstance(Collection)->PostEditChange();
}
TSet<FName> ParameterNames;
for (int oldVector = 0; oldVector < Collection->VectorParameters.Num(); oldVector++)
{
ParameterNames.Add(Collection->VectorParameters[oldVector].ParameterName);
}
for (int oldScalar = 0; oldScalar < Collection->ScalarParameters.Num(); oldScalar++)
{
ParameterNames.Add(Collection->ScalarParameters[oldScalar].ParameterName);
}
// Go through all materials in memory and recompile them if they use this material parameter collection
for (TObjectIterator<UMaterial> It; It; ++It)
{
UMaterial* CurrentMaterial = *It;
bool bRecompile = false;
// Preview materials often use expressions for rendering that are not in their Expressions array,
// And therefore their MaterialParameterCollectionInfos are not up to date.
if (CurrentMaterial->bIsPreviewMaterial)
{
bRecompile = true;
}
else
{
for (int32 FunctionIndex = 0; FunctionIndex < CurrentMaterial->MaterialParameterCollectionInfos.Num() && !bRecompile; FunctionIndex++)
{
if (CurrentMaterial->MaterialParameterCollectionInfos[FunctionIndex].ParameterCollection == Collection)
{
TArray<UMaterialExpressionCollectionParameter*> CollectionParameters;
CurrentMaterial->GetAllExpressionsInMaterialAndFunctionsOfType(CollectionParameters);
for (UMaterialExpressionCollectionParameter* CollectionParameter : CollectionParameters)
{
if (ParameterNames.Contains(CollectionParameter->ParameterName))
{
bRecompile = true;
break;
}
}
}
}
}
if (bRecompile)
{
// Propagate the change to this material
UE_LOG(LogTemp, Warning, TEXT("MP--1157: Update Material"));
CurrentMaterial->PreEditChange(NULL);
CurrentMaterial->PostEditChange();
CurrentMaterial->MarkPackageDirty();
}
}
1 Like