Create MaterialInstanceConstant from editor tool


Is there currently any way to create (from within editor tool) MaterialInstanceConstant and set various static switches at it to true/false ?
I see methods to get switches names, but no methods to set’em.
It’s possible at all without modifying engine ?

I want to create tool that will automatically go thru all my (selected) materials, create all possible combinations (in terms of static switches) from then, the save them in content browser, put some template meshes on the scene, and assign those material instances to them, to compose level.
Why ?
Couse I’m using level streaming on android and there is an noticable chickup each time new shader comes in (it’s need to be compiled, and it takes a lot of time. So my idea is to create (it possible automatically) level that will have all shader
permutations that possibly can exist in the level. And this level will be streamed as first one to precache all shaders.

Or there is a better way to do this ? (there is about 100 - 200 permutations in whole game, as I count this, so doing this by hand is a LOT of clicking, and as the shader artist will add new material (shader), it also need to be added to this ‘precache level’
all this is very error prone … so I’m looking for some automated solution.

I’v figured this out after a while …
for the record:

				FAssetToolsModule &AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools");

				UMaterialInstanceConstantFactoryNew* Factory = NewObject<UMaterialInstanceConstantFactoryNew>();
													 Factory->InitialParent = UMaterial_that_we_want_to_be_Parent;

				UMaterialInstanceConstant *MInst = CastChecked<UMaterialInstanceConstant>(AssetToolsModule.Get().CreateAsset(Name, FPackageName::GetLongPackagePath(PackageName), UMaterialInstanceConstant::StaticClass(), Factory));

				if (MInst)
					MInst->PostEditChange(); // This is critical, without this one, strange things happen while serializing !!!

And SUPER_HACK to set static switches :wink:

						// Get list of static switches
						TArray<FName> SWNames;
						TArray<FGuid> SWGUIDS;
						UMaterial_that_we_want_to_be_Parent->GetAllParameterNames<UMaterialExpressionStaticBoolParameter>(SWNames, SWGUIDS);

						const FStaticParameterSet &StaticParams = MInst->GetStaticParameters(); 

						TArray<FStaticSwitchParameter> *_Arr = (TArray<FStaticSwitchParameter> *)&StaticParams.StaticSwitchParameters; // HACK !!!! cast const to non-const ;)
						TArray<FStaticSwitchParameter> &StaticSwitches = *_Arr;
						// NOTE::Better check first if StaticSwitches arrah have entry for switch you like to modify/add !!

								FStaticSwitchParameter Switch;
								Switch.bOverride	  = true;
								Switch.Value		  = true_or_false;
								Switch.ParameterName  = SWNames[_index_you_like_];
								Switch.ExpressionGUID = SWGUIDS[_index_you_like_];



and to stop about linker complains add this to your module (this function is not exposed from engine so needs to be duplicated for this to work (another hack :wink:

void UMaterialExpressionParameter::GetAllParameterNames(TArray<FName> &OutParameterNames, TArray<FGuid> &OutParameterIds) const
	int32 CurrentSize = OutParameterNames.Num();
	if(CurrentSize != OutParameterNames.Num())

but after all those hacks I have properly working automata that allows me to create all possible permutations and put’em into level for precaching …

So could you override the texture parameters that already assigned on MaterialInstance to another UTexture?
I actually follow you way then successfully to create material instance but stuck in override texture parameter.

Hi, Textures can be set in ‘normal’ way (there is a function for that in DynamicMaterialInstance - follow what it do and do that same for static instance :slight_smile:

Thank you,

I found a builtin function is SetTextureParameterValueEditorOnly that exactly what i really expect.
Anyway thank so much.