I have a master material, with about 10 static switches to change the behaviour of the material.
I want to auto generate a new material for each possible permutation of static switch settings, and put these materials into an array that can be accessed in-game.
Anyone know if this is possible?
The reason i need this this, Is I want to give the player control over the static switches in-game.
I have considered using editor utilities to do this, however I don’t see a way to set material instance static switch parameters with these.
Switches are not meant to be changed in runtime. They are meant for developers. It compiles any material instances with these settings before packaging.
If you want switching for the player, use lerps with a param for the alpha. This does make the shader more expensive because the calculations are present but not visible.
I’m sure there are more optimal methods, but not without digging deep into the engine.
Yes it is very much possible, not sure about blueprint but with C++ it’s not even that hard.
I’d went with enum approach where each static switch corresponds to enum flag.
Then if you just iterate through all of the flags and sum them together you’ll get the number of possible combinations. Then just loop from 0 to this number and check which flag is on and set the static switch to enabled/disabled.
So if you have master material, you can just create new material instance by CreateAsset method from AssetTools module, for that you need to create UMaterialInstanceConstantFactoryNew and set its InitialParent variable to your master material and after you’ve created the material instance you can just call SetStaticSwitchParameterValueEditorOnly where argument will be the result of the enum flag presence in the iteration counter.
Then you can do whatever you want with that asset - e.g. adding it to and array of some primary asset instance and as last step call UEditorAssetLibrary::SaveLoadedAsset to actualy save it.
Then during runtime you can just specify with enum flags what features the material should have (Flag1 | Flag2 | Flag5) and cast that to an int32 and that is the index to the array where you stored the material with those exact flags turned on. This applies if you want really all possible combinations.
If you want only some and you have some dependencies etc., you can use UMETA() macro with something like UMETA(MyMetaData = GroupBeta) and you can use StaticEnum template to get these metadata and decide what to do during generation depending on them.
With this though, you cannot use array but you have to resort to using TMap as you’ll have “gaps” in your indices, otherwise it will work the same, but you have to make sure there is no way during runtime you’ll ask for a combination you did not create.
Obviously all of this can be done only in EDITOR, but after the materials are generated, you can work with them in shipped projects no problem. But be careful with the amount of flags. Just for 6 of them you will create 64 permutations of the material and it grows really fast so with 10 switches you are getting into thousands territory - and that’s just for that single master material and permutations created by you, not including “behind the scenes” permutations engine has to generate for you.