How to change the active material of an object while game is running?

Why can a mesh have more than one material slot. You are only able to have one active material on a face. What is the reason for having multiple material slots?

Is there a way so swap out the active material while a game is running. I found this code that will swap the material in slot 0 with the one is slot 1, but the texture of my object never changes.

a=bge.logic.getSceneList()[0].objects.get('Bedrock') #select object Cube

        print((a.meshes[0].materials )  ) #show its materials
        mat=a.meshes[0].materials[0]  #copy current material
        a.meshes[0].replaceMaterial(0, a.meshes[0].materials[1] )  #replace first material with the second (which has different color of curse :-)
        a.meshes[0].replaceMaterial(1, mat) #copy the 1st material to 2nd slot
        print((a.meshes[0].materials )  ) #show materials list

This will swap material 0 and material 1, but the texture will not change.

This code below will change the texture on the active material.

ID = texture.materialID(a, 'MABedrock')

    # create a texture object
        object_texture = texture.Texture(a, ID)

    # create a new source with an external image
        url = logic.expandPath("//Textures/bedrock.png")
        new_source = texture.ImageFFmpeg(url)

    # the texture has to be stored in a permanent Python object
        logic.texture = object_texture

    # update/replace the texture
        #logic.texture.source = new_source
        logic.texture.refresh(False)

How do I get the active material to change and have the texture of my object change to the one of the new active material?

i have made a test file for you that is working… i remember many years ago, when i made a commercial application with bge 2.49 or so — VideoTexture was pure pain :slight_smile: … because i had no idea

check out on github:

https://github.com/sevi78/UPBGE-Tests

look for VideoTextureTest

2 Likes

What version of the engine are you using? UPBGE 3.0 supports using bpy, which is how I do this.

sidequestion: i remember in the past (2.49 or so —), that bpy doesn’t work on runtimes. has this changed? would be great

Bpy works in game in 3x

But you need to use it.

import bge
cont =bge.logic.getCurrentController() 
own = cont.owner 
Mesh = own.blenderObject

Kx_meshProxy is replaced with blender mesh / or bmesh api.

0.3.0

The idea is that I will have 5+ blocks. They will all share the same model, but have different textures. So instead of creating 5+ models of the same cube and assigning a different materials, I was wondering if I could just create one block model and assign it the correct material when I spawn it into the world.

if you want them to exist at the same time, then you will need to have five different objects (afaik). But if they only exist one at a time, then the following should work:

a = bge.logic.getSceneList()[0].objects.get(‘Bedrock’)
a.blenderObject.active_material = bpy.data.materials[“myMaterialName”]

We can unwrap to the bottom of an atlas, and add object color to the uv, offsetting it. (in shader nodes)

This way everything is 1 material