Apply or change materials on skeletal meshes with Python

Hey there,

is there a way to apply materials to a skeletal mesh with Python?
Unfortunately it isn’t the same as for static meshes where I can set them like this:


MyStaticMesh.set_material(MaterialSlotNumber, MyMaterial)

I discovered just a material-array, that I can get from a skeletal mesh and the documentation says it is read-only.

I would be thankful for any kind of suggestions.
Thank you in advance for your help and time.

Hm, the documentation for that materials member says that it’s read only, but the documentation for the property at the top of the page under Editor Properties says it’s read-write.

What happens if you use get_editor_property(“materials”) to retrieve the array of materials, make your substitution, then call set_editor_property(“materials”, my_array) to make it use your new set?

I think the problem is, that we get a struct property and also need to set the material as a struct. The documentation may be not exact on this point. We don’t get a list of skeletal materials, we get an array of material structs. We can convert them to materialinterfaces (and use them like normal), but we can’t insert them easily back, because we need them to be in a type struct. I couldn’t found a way to convert from material to a struct right now.
Would be interested in a solution.

After some research and thanks to the Anton’s tip, I figure out how to change the materials on the skeletal mesh, it needs to create a new list and replace the old one, it does not work just change the existing list values here is my example code, I don’t know if is the best way to do it but this worked for me:

    # This is for the future, in case we want to create and set more materials [MATERIALINSTANCE,SlotName]
    materialsTupple = ([materialInstanceRef, 'SlotName'], [materialInstanceRef, 'SlotName'], [materialInstanceRef, 'SlotName'], [materialInstanceRef, 'SlotName')

   # Create an empty list to generate a copy of the original list adding the new simple material reference this was necessary
    refreshedMaterials = []
    for material in asset.materials:
        refreshedMaterials.append(material)

    for i in range(len(refreshedMaterials)):
        for t in range(len(materialsTupple)):
           SetNewMaterial(i, refreshedMaterials, materialsTupple[t])
               
    asset.materials = refreshedMaterials

# This create a new Skeletal material and set it if the material slot is empty.
def SetNewMaterial(index=0, newMaterials=[], materialsTupple=()):
    if newMaterials[index].material_slot_name == materialsTupple[1]:
        if newMaterials[index].material_interface is None:
            newMaterial = SkeletalMaterial(material_interface=materialsTupple[0], material_slot_name=materialsTupple[1], uv_channel_data=newMaterials[index].uv_channel_data)
            newMaterials[index] = newMaterial

In my example, I just set the material if the slot is empty… I hope this can be usefull :smile:

2 Likes