I have some trouble with linked objects over different blend files.
When I add an object (group_instance) from an other blend from an inactive layer in game the mesh of the object didn’t get update to the position of the instance empty.
test script not finished!
in that case for example grass:
from bge import logic, render
from mathutils import Vector
import random
grass_emitter = logic.getCurrentController().owner
scene = grass_emitter.scene
ObjList = scene.objects
ObjInactList = scene.objectsInactive
rad_range = grass_emitter['Range']
emit_number = grass_emitter['Number']
ground = grass_emitter['Underground']
#random.seed("Whatever")
class Grass():
def __init__(self):
self.spawn_obj_list = [o for o in ObjInactList if 'spawn_group' in o if o['spawn_group'] == ground]
def random_spawn_obj(self):
choice = random.choice(self.spawn_obj_list)
return choice
def range_player(self, obj):
rand_rot = obj.worldOrientation.to_euler()
rand_rot.z+=random.uniform(-rad_range*.5, rad_range*.5)
X = obj.worldPosition.x + random.uniform(-rad_range*.5, rad_range*.5)
Y = obj.worldPosition.y + random.uniform(-rad_range*.5, rad_range*.5)
Z = obj.worldPosition.z -5
max_range = Vector([X,Y,Z])
return (rand_rot, max_range)
def spawn_position(self):
rot, end = self.range_player(grass_emitter)
start = end.copy()
start.z+=10
end = rot.to_matrix()*end
start = rot.to_matrix()*start
ray = grass_emitter.rayCast(end, start, 0, ground, 0, 1, 0)
render.drawLine(start, end, [0, 0, 255])
if ray[0]:
spawn_obj = self.random_spawn_obj()
self.applie_obj(spawn_obj, ray[1])
else:
pass
def applie_obj(self, obj, pos):
added_obj = scene.addObject(str(obj), None, 0)
added_obj.worldPosition = pos
#def delete_obj(self, obj):
def main(self):
for i in range(emit_number):
self.spawn_position()
grass = Grass()
def main():
grass.main()
Be aware that when you copy instances with addObject you copy all objects. The returned object will be the instantiating object (the empty). Without further action it has no parent/child relationship to the instance members.
[Btw. it does not matter if the instance is linked from a different file.]
In other words:
addObject creates:
the emtpy
the grass mesh objects
it returns the empty.
As the grass meshes are not parented to the empty they will not follow the explicit position change of it.
Solution A):
Parent the group members to the empty before moving the empty.
added_instantiator = scene.addObject(str(obj), None, 0)
for instanceMember in added_instantiator.groupMembers:
...
Sitenotes:
Your code contains some misleading names:
Grass = it tells this is a Grass class which behaves like grass, but does it really behave like grass? [Isn’t it a grass builder/factory?]
random_spawn_obj = in difference to the name it does not spawn obj but randomly selects an object out of existing objects
range_player = I’m not sure what it does. It looks like it does some random calculation. But I do not see a player
spawn_position = sounds like it spawns a position - which is either strange grammar or means something else … it returns a position. A verb (like get, calculate, find, determine) would make it more visible to me.
applie_obj = shouldn’t this be an “y”? The first question that comes to my mind: Apply to what? I suggest to call it spawn_object(), or spawn_grass(), add_grass(), create_grass() or simply spawn().