# How do I change UV coordinates while the game engine is running?

I'd like to do a map in a game that moves with the actor. What is the proper syntax to move uv coordinates around and have the game engine update the result?

## 2 Answers

If you want to perform a linear transform such as translate or scale over all UVs, you can use the mesh.transformUV function. To use this function, you would usually set up two channels like so:

uv_offset = [0, 0]
def init(c):
# Copy UVs to second channel using an identity matrix.
c.owner.meshes[0].transformUV(-1, mathutils.Matrix(), 1, 0)


Thereafter you can transform from that second channel using a custom matrix:

def update(c):
# Transform stored original values and write to first channel.
uv_offset[0] += SPEED_X
uv_offset[1] += SPEED_Y
uv_mat = mathutils.Matrix.Translation((uv_offset[0], uv_offset[1], 0))
c.owner.meshes[0].transformUV(-1, uv_mat, 0, 1)


This avoids the need to iterate over the vertices in your script, so it may be faster for large meshes. You can also perform multiple transforms at once, e.g. scale and translate, by multiplying two matrices together.

• Very interesting! Could you explain in your answer what you mean by 'channels'? Assume the reader having very little knowledge. – Haunt_House Sep 15 '13 at 14:35
• Actually I'm not sure! Maybe this would conflict with the multiple UV maps that a mesh can have. In any case if your mesh only has one UV map, this code should be fine. – z0r Sep 15 '13 at 14:49

After another search session, I found the answer here:

For a working blendfile, see the Blenderartists thread, thanks to HG1

from bge import logic # get the controller that executes the script
cont = logic.getCurrentController() # get the object that uses the controller
own = cont.owner

speed_x = 0.002 # speed by which the coordinates are moved
speed_y = 0.0   # speed by which the coordinates are moved
mesh = own.meshes[0] # access the mesh of the object in question
v_array = mesh.getVertexArrayLength(0) # how many verts are there?
for v in range(0,v_array): # go through the uv's of every vert
vert = mesh.getVertex(0,v)
uv = vert.getUV()
uv[0] += speed_x # change the uv coordinates. uv[0] = x, uv[1] = y
uv[1] += speed_y
vert.setUV(uv) # get the game engine to notice the change!!


The name of your script belongs into the controller.

• It hasn't been my intention to answer my own question when I asked it, but since I found the solution in the meantime... If anything is outdated or improvable, make a second answer and I'll approve that. – Haunt_House Sep 15 '13 at 14:02
• It's fine to answer your own question, it is even encouraged if you have a great answer – zeffii Sep 15 '13 at 14:27