MaterialParameterCollection changes on Editor

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