NOTICE : I just found out you just can select all seperated objects, go into Edit Mode and then create a UV Map for all of them at once. But I will let stand this article here for documentation purposes. 😀
I have a set of tiles, for example a castle. So I wanted to use just one UV Map for all of them, but I still needed them as single objects.
Doing this by hand is tedious. So I managed to find and adapt two python scripts, who do this for you.

As you can see every object has a name, that I will later need in the game engine, for example in Unity3D, to make a Prefab out of it.
So with every object selected, I use a script I adapted to generate a vertex group for every object for all its verticies in one group, which is named exactly as the object is named.

import bpy
selection_names = [obj.name for obj in bpy.context.selected_objects]
#adds all vertices to a vertix group with the object name
for name in selection_names:
vg = bpy.data.objects[name].vertex_groups.new(name=name)
verts = []
for vert in bpy.data.objects[name].data.vertices:
verts.append(vert.index)
vg.add(verts, 1.0, 'ADD')
After that I join all the objects with Ctrl-J as usual, resulting in only one Object but all the vertex groups are still set correctly.
Then I auto-create the UV Map for the single object.
With this script ( I have to find where I found it again and by whom ) then I automatically seperate every object using the vertex groups and the name of the vertex group.
# coding=utf8
import bpy
def main():
origin_name = bpy.context.active_object.name
keys = bpy.context.object.vertex_groups.keys()
real_keys = []
for gr in keys:
bpy.ops.object.mode_set(mode="EDIT")
# Set the vertex group as active
bpy.ops.object.vertex_group_set_active(group=gr)
# Deselect all verts and select only current VG
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.vertex_group_select()
# bpy.ops.mesh.select_all(action='INVERT')
try:
bpy.ops.mesh.separate(type="SELECTED")
real_keys.append(gr)
except:
pass
for i in range(1, len(real_keys) + 1):
bpy.data.objects['{}.{:03d}'.format(origin_name, i)].name = '{}.{}'.format(
origin_name, real_keys[i - 1])
if __name__ == '__main__':
main()
After that I have all the objects seperated named correctly, using their part of the shared UVMAP. 😀
Now I use the combined one to paint it in a PBR Software like Substance Painter or Armor Paint to generate the big texture using the combined texture.
This approach saves me hours. It might not be the best thing to use big 2K textures but it saves loading time and makes changing whole tilesets textures easier.




