adding specific objects

Okay, I have this code that generates a random mesh from inactive layers and it works great.

import bge
import random

def main():

cont = bge.logic.getCurrentController()
own = cont.owner


scene = bge.logic.getCurrentScene()

objects = scene.objectsInactive

print(objects)

choice = random.choice(objects)

print(choice)

scene.addObject(choice, own, 200)

main()

However, is there a way to have it so that it only generates specific objects from inactive layers or adds objects from specific layers. I’m asking because I’m adding two emptys and I want them to generate different objects.

run module mode, not script mode.


import random

def main(cont):

own     = cont.owner
scene   = own.scene

objects = [obj for obj in scene.objectsInactive if 'a_property_name' in obj]
choice  = random.choice(objects)

added_object = scene.addObject(choice, own, 200)

objects - now loops trough the objects and searches for a property, so only objects with a specific property gets into the objects list.

added_object - i made a variable out of the added object, the object gets placed just like before, but now you can give additional commands to it if needed. Something like:
.worldPosition or set a property, etc.

cont and scene - the function method sets the first argument as a controller, so we can leave cont = away. and scene can be grabbed by the object in this case the own, this means it grabs the scene where the owner is.

#oops forgot to put import random

I’m trying the code but doesn’t work. Console keeps saying ‘no module named’ whatever.

please use code tags when posting code. Otherwise the code is nearly undreadable.

Your issue has nothing to do with module or script mode. The mode determines how you need to structure your code. Unfortunately you chose the worst of both worlds: using function definitions without a need. More worse - it does not even provide useful information to the reader.

All you need is to filter the objects by a criteria of your choice. Cotax showed a fine example - filtering by property existence.

I suggest this code:

Script: addRandomObject.py

addRandomObject.py


import bge
import random

transformationProvider = bge.logic.getCurrentController().owner
scene = bge.logic.getCurrentScene()

filterProperty = "addable"
templateObjects = [object for object in scene.objectsInactive 
                   if filterProperty in object]
templateObject = random.choice(templateObjects)
scene.addObject(templateObject, transformationProvider, 200)

or
Module: objectAdder.addRandomObject

objectAdder.py


import random

def addRandomObject(controller):
    transformationProvider = controller.owner
    scene = controller.owner.scene

    filterProperty = "addable"
    templateObjects = [object for object in scene.objectsInactive 
                       if filterProperty in object]
    templateObject = random.choice(templateObjects)
    scene.addObject(templateObject, transformationProvider, 200)

Be aware this code does not evaluate the connected sensors. It will add one object at each single execute.

I’m trying the code but doesn’t work. Console keeps saying ‘no module named’ whatever.

Sorry, module mode needs a scriptname.function, So in this case: scriptname.main and you need to name the script scriptname.py.

Monster’s code works great. Only problem is I don’t know how to control the length between each generation

…see below …:rolleyes:

one way is move the object spawner each time it add something
,adding only one object at time



import bge
import random

transformationProvider = bge.logic.getCurrentController().owner
scene = bge.logic.getCurrentScene()

filterProperty = "addable"
templateObjects = [object for object in scene.objectsInactive 
                   if filterProperty in object]
templateObject = random.choice(templateObjects)
scene.addObject(templateObject, transformationProvider, 200)
size = 3.0
own.worldPosition.x += size


otherwise move the object added directly inside a unique loop:


import bge
import random

transformationProvider = bge.logic.getCurrentController().owner
scene = bge.logic.getCurrentScene()

filterProperty = "addable"
templateObjects = [object for object in scene.objectsInactive 
                   if filterProperty in object]
templateObject = random.choice(templateObjects)

size = 3.0
for x in range(10):
    ob = scene.addObject(templateObject, transformationProvider, 200)
    ob.worldPosition.x += x * size 


more cool:


import bge
import random

transformationProvider = bge.logic.getCurrentController().owner
scene = bge.logic.getCurrentScene()

filterProperty = "addable"
templateObjects = [object for object in scene.objectsInactive 
                   if filterProperty in object]


size = 3.0
for x in range(10):
    for y in range(10):
        templateObject = random.choice(templateObjects)
        ob = scene.addObject(templateObject, transformationProvider, 200)
        ob.worldPosition.x += x * size
        ob.worldPosition.y += y * size

You mean the time between creating objects? This is a matter of the sensors.

Whenever a sensor triggers the code gets executed. When the code gets executed an object gets added.

Sensors sense events. So you already have an event handling system. The sensor represents the event, the controller/actuator represents the operation.

Remark: As usual you need to evaluate the sensor status within your controller’s code.