Ever wanted to LibLoad multiple of the same object? No? I’m not really surprised.
Use:
However many identical meshes you like with different UV layouts, without having to duplicate them inside a blend
Same thing for Vertex Colors, materials, or any mesh-based property. (ie you can change the material on one mesh without affecting the others)
Requirements:
Object you want to add is on a hidden layer in the blend to LibLoad
import bge
byte_strings = {}
def add_unique(obj_name, identifier, ref_obj, file_name):
'''Loads a unique instance of an object.
INPUTS:
- obj_name, the name of the object to add
- identifier, the library-name to store the object under (will have a number added after it)
- ref_obj, where to add the object
- file_name, where the object resides (string)
OUTPUTS:
- added_object, the object that was added
'''
if obj_name not in byte_strings:
path = bge.logic.expandPath(file_name)
byte_strings['obj_name'] = open(path, 'rb').read()
identifier = identifier + str(0)
while identifier in bge.logic.LibList():
identifier = identifier+str(int(identifier[-1])+1)
bge.logic.LibLoad(identifier, 'Scene', byte_strings['obj_name'])
scene = bge.logic.getCurrentScene()
new_obj = [o for o in scene.objectsInactive if o.name == obj_name and 'old' not in o][0]
new_obj['old'] = 0
added_obj = scene.addObject(new_obj, ref_obj)
return added_obj
In my case, loaded objects need to be added right away, but if you want want to get a reference to the added object on the inactive layer, then just remove the line starting with ‘added_obj’ and replace the ‘return added_obj’ with ‘return new_obj’
Have fun with it (for those of you who ever use this sort of code)
If you’re texturing object using GLSL code (asgiven here), then you can set the material for one object separately from another object.
Normally if you apply a shader like that to one object, all of it’s duplicates will inherit the same shader (because they share the mesh). If you’re libloaded like this, then it’s an independant mesh, so it can be object-specific.
I have not actually tried that yet though, just theorized about it. I also haven’t seen a point for changing material like that, for me, the reason for this code was vertex colors.
I revised this snippet today to work with multiple objects and to do so in a simpler way:
def unique_libload(file_path):
'''Loads a unique instance of a blend.
INPUTS:
- file_path - path to the blend file
OUTPUTS:
- added_objects, the object that were added
'''
scene = bge.logic.getCurrentScene()
old_objects = scene.objects + scene.objectsInactive
f = open(file_path, 'rb').read()
identifier = file_path + str(0)
while identifier in bge.logic.LibList():
identifier = identifier+str(int(identifier[-1])+1)
bge.logic.LibLoad(identifier, 'Scene', f)
all_obj = scene.objects + scene.objectsInactive
added_objects = []
for o in all_obj:
if o not in old_objects:
added_objects.append(o)
return added_objects
It will load the blend and return a list of added objects. If you have lots of objects in your scene it may cause lag, but then libload will cause lag anyway…
If I do this (libLoad unique mesh with unique materials) and delete a object,
Can I simply spawn a copy of the hidden layer object, and replace mesh with the libLoad mesh?
EndObject() of a libNew does not libFree the mesh correct?
I am going to do
If “uniqueMeshName” does not exist:
(libload trick to make mesh, name it uniquemeshname)
Else:
Add object(blank pecs card) set mesh to uniqueMeshName
In 90% of cases you should use LIbNew instead of LibLoadUnique. LibLoadUnique is painfully slow. Like, really, glacially slow. Only do it at load-time. It also frequently loses relative paths. IN other words: it’s probably not want you want. Just use LibNew (unless you need to duplicate materials or textures).
What are you actually trying to do here? (ie what is the desired outcome, not what code are you planning to write).
Yes, you need to make sure you free things properly. endObject is not sufficient. In the years since writing this snippet, I have vastly improved how I manage libloads, and have several nice constructs around them to simplify this process. I’ll have to polish them and upload at some point.
Remember that now you have non-unique mesh names. You’ll have to make sure you use the correct mesh. I don’t think you can rename meshes.