How to edit/add the material layers of a Material or MaterialInstanceConstant with the python api

I’m trying to dynamically edit a material instance to change the material layers in python but the documentation is not really clear how to do it.

I find a lot of different classes in the documentation that seem to be related to this such as the MaterialParameterInfo or MaterialLayersFunctions but I fail to see how I can use these class from a Material I would create from the python api.

Answering my own question for anybody who would be looking for that as well.
Currently, the API to edit the layers of a material are not exposed to the blueprints.

I created a plugin to be able to manipulate these with blueprints and python and published it on github. Feel free to copy the code:

(and here a direct link to the relevant class: UEAdvancedMaterialEditingLibrary/LayeredMaterialLibrary.h at main · njibhu/UEAdvancedMaterialEditingLibrary · GitHub )

3 Likes

Where should I locate these files.
I have tried to located the plugins at “…/Plugins/AdvancedMaterialEditingLibrary” and this one contains “AdvancedMaterialEditingLibrary.uplugin” and “Resources”
For the “Source” file it contains “AdvancedMaterialEditingLibrary” in this one we have 2 folders and 1 files, 2 folders are: “Private” and “Public”, the last one is “AdvancedMaterialEditingLibrary.Build.cs”

Hi Njibhu,

i big thank you for this nice +C+ class

I put here just a simple class inherited from yours to have automatic completion

have a nice day everyone

import unreal

class LayeredMaterialLibrary:
    
    @staticmethod
    def get_layer_count(instance):
        return unreal.LayeredMaterialLibrary.get_layer_count(instance)

    @staticmethod
    def add_material_layer(instance):
        return unreal.LayeredMaterialLibrary.add_material_layer(instance)

    @staticmethod
    def is_layered_material(instance):
        return unreal.LayeredMaterialLibrary.is_layered_material(instance)

    @staticmethod
    def assign_layer_material(instance, layer_index, new_layer_function):
        return unreal.LayeredMaterialLibrary.assign_layer_material(instance, layer_index, new_layer_function)

    @staticmethod
    def assign_blend_layer(instance, layer_index, new_blend_layer_function):
        return unreal.LayeredMaterialLibrary.assign_blend_layer(instance, layer_index, new_blend_layer_function)

    @staticmethod
    def get_layered_material_scalar_parameter_value(instance, parameter_name, layer_index):
        return unreal.LayeredMaterialLibrary.get_layered_material_scalar_parameter_value(instance, parameter_name, layer_index)

    @staticmethod
    def set_layered_material_scalar_parameter_value(instance, parameter_name, layer_index, value):
        return unreal.LayeredMaterialLibrary.set_layered_material_scalar_parameter_value(instance, parameter_name, layer_index, value)

    @staticmethod
    def get_layered_material_static_switch_parameter_value(instance, parameter_name, layer_index):
        return unreal.LayeredMaterialLibrary.get_layered_material_static_switch_parameter_value(instance, parameter_name, layer_index)

    @staticmethod
    def set_layered_material_static_switch_parameter_value(instance, parameter_name, layer_index, value):
       return unreal.LayeredMaterialLibrary.set_layered_material_static_switch_parameter_value(instance, parameter_name, layer_index, value)

    @staticmethod
    def get_layered_material_texture_parameter_value(instance, parameter_name, layer_index):
        return unreal.LayeredMaterialLibrary.get_layered_material_texture_parameter_value(instance, parameter_name, layer_index)

    @staticmethod
    def set_layered_material_texture_parameter_value(instance, parameter_name, layer_index, value):
        return unreal.LayeredMaterialLibrary.set_layered_material_texture_parameter_value(instance, parameter_name, layer_index, value)

# Example usage
if __name__ == "__main__":
    instance = unreal.load_object(None, '/Game/AP_MaterialLibrary/CommonMaterial/CommonLayer/testPython')
    new_layer_function = unreal.load_object(None, '/Game/AP_MaterialLibrary/LayerMaterial/ML_Master/ML_PLANAR_LAYER')
    new_blend_layer_function = unreal.load_object(None, '/Game/AP_MaterialLibrary/LayerMaterial/ML_Blend/MLB_PlanarAngleHeightVertexRadialMaskAutoAxe')
    parameter_name = 'Metallic'
    layer_index = 0
    value = .5

    #LayeredMaterialLibrary.refresh_editor_material_instance(instance)
    print(instance)
    print(LayeredMaterialLibrary.get_layer_count(instance))
    LayeredMaterialLibrary.add_material_layer(instance)
    print(LayeredMaterialLibrary.is_layered_material(instance))
    LayeredMaterialLibrary.assign_layer_material(instance, layer_index, new_layer_function)
    layer_index = 1
    LayeredMaterialLibrary.assign_layer_material(instance, layer_index, new_layer_function)
    LayeredMaterialLibrary.assign_blend_layer(instance, layer_index, new_blend_layer_function)
    print(LayeredMaterialLibrary.get_layered_material_scalar_parameter_value(instance, parameter_name, layer_index))
    LayeredMaterialLibrary.set_layered_material_scalar_parameter_value(instance, parameter_name, layer_index, value)
    parameter_name = 'Normal Map ?'
    print(LayeredMaterialLibrary.get_layered_material_static_switch_parameter_value(instance, parameter_name, layer_index))
    LayeredMaterialLibrary.set_layered_material_static_switch_parameter_value(instance, parameter_name, layer_index, True)
    parameter_name = 'Normal_Map'
    print(LayeredMaterialLibrary.get_layered_material_texture_parameter_value(instance, parameter_name, layer_index))
    #LayeredMaterialLibrary.set_layered_material_texture_parameter_value(instance, parameter_name, layer_index, unreal.load_object(None, '/Game/Path/To/Your/Texture'))