hello, I was wondering if there’s a way to access (and manipulate) individual objects added? maybe through index? any help would be appreciated .
You can use the objectLastCreated attribute which is an attribute of the edit object actuator (when it is set to add objects).
Storing a lot of objects that have been created using the same actuator is a bit trickier though, because the objectLastCreated attribute only stores the most recently created object (you would need to find a way to extract the information into a list or a dictionary or something of that sort).
Actually, I’ve already worked with that, I found a way to get every object last created with an add object actuator in the scene and append them in a list, but what I was wondering is, is there a way to communicate with a particular added object like send a message to it or change a property value. I don’t know if I can access an object through the list and change it or if the lists is just keeping record of the added objects, sorry I should have been more specific :o.
You still haven’t been very clear of:
- What you want to achieve
- What the problem is
- What code you are using
Yes, you can edit whatever you like about a game object by storing and retrieving it’s handle in a list.
Some issues you may be facing:
- variables aren’t maintained across frames, so you may have to store it in the globaldict, use a module rather than a script etc.
- Don’t store the names, store the handle. Names are not unique.
Further than that, I can’t help you without more detail.
However, I’ll pump out some code that will hopefully help.
So you can create an object with the add object actuator:
cont = bge.logic.getCurrentController() own = cont.owner add = cont.actuators['addObject'] cont.activate(add)
Then say, on the next frame:
add_object_list += add.objectLastCreated
And then when you want to use the object:
for obj in add_object_list: obj['property'] = 'whatever'
No idea if that helped at all.
It might actually, but I need to try it on a different computer. This one is Ubuntu so I can’t access a console for errors.
I do all my coding blender development from Ubuntu.
Simply start a terminal, and start blender from there. If you’re using blender installed from the software center, you can just type ‘blender’ into the terminal.
If you downloaded it from the blender website you may have to type something like:
okay thanks, I’ll try it
What are you trying to do with the objects?
you can store it in a property: (avoiding the mistakes of SCA)
cube = scene.addObject(“cube”, own)
own[“cube”] = cube
in line 1 is created , in line 2 is ready to use! (not as SCA :D)
You store a reference to itself in a property of it’s own :spin:?
You shouldn’t focus to much on avoiding the cleanness of SCA ;).
Without knowing the background of the request it is hard to guess what a sufficient solution is.
- the objects are part of KX_Scene.objects
- the objects share the same name (the original is inactive and therefore not in the list)
so it is very easy to filter them out.
from bge.logic import getCurrentScene ... addedCubes = findObjectsByName("Cube") ... def findObjectsByName(objectName): return [object for object in getCurrentScene().objects if object.name == objectName]
“own” is the spawner!
a example to get the reference of a obj created: (require that “Cube.001” exist in another layer)
import bge cont = bge.logic.getCurrentController() own = cont.owner # the obj that spawn if not "init" in own : #this statement is supposed to be true only one time own["init"] = 1 scene = own.scene # is the same of -> bge.logic.getCurrentScene() newObj = scene.addObject("Cube.001", own) newObj.setParent(own) newObj.localPosition.x = 5.0 own["cube1"] = newObj # store the obj inside a property #another obj with the same name, but is another!! newObj = scene.addObject("Cube.001", own) newObj.setParent(own) newObj.localPosition.x = -5.0 own["cube2"] = newObj # store the obj inside a property c1 = own["cube1"] # get the obj from the property c2 = own["cube2"] # get the obj from the property c1.applyRotation((0,0, 0.05),1) # manipulation c2.applyRotation((0,0.05,0),1) # manipulation
PS: the reference can bercome invalid !
I believe is easier, “Cube” is in inactive layer
cube1 = bge.logic.getCurrentScene().objectsInactive["Cube"] cube2 = bge.logic.getCurrentScene().objectsInactive["Cube"]
You could to use a vector or map also
Sorry I haven’t been on for a couple of days. To be more clear on what I want to achieve ,since I’ve been so mysterious ;), I want to make a list of all added objects so I’m able to access each one’s features, kinda like scene.object[‘object’]. Now I know that you simply can’t access an added object in a list by name if a lot of other objects in the list have the same name, so I’ve been trying to get the object’s number index when the mouse cursor touches it (this is what I’ve been recently trying to do), but it hasn’t worked.
Here’s the script so far.
import bge def main(cont): own = cont.owner mouse = cont.sensors['Mouse'] scene = bge.logic.getCurrentScene() obj = scene.objects lst1 =  for i in obj: for n in i.actuators: if type(n) == bge.types.KX_SCA_AddObjectActuator: lst1.append (n.objectLastCreated) if mouse.hitObject in lst1: print(lst1.index(mouse.hitObject))
Whenever I check the console I get just the same number almost all the time
I am sorry for not being very descriptive before, hopefully this will help a bit.
one more thing I forgot to mention is I can’t seem to keep every thing appended to lst1. It doesn’t want to hold everything.
A number index belongs to a specific list. So you need the combination of the list and the index. If you do not create and maintain the list by yourself it is dangerous to keep the index alone. The reason is simple if anything (e.g. the bge) removes or inserts items of the list the index becomes incorrect.
This is what we wanted to know! I guess you really meant - the visible object the system mouse cursor is over ;).
But there is no real relationship to added objects. Such things should not care if objects are dynamically added or not. So you can ignore the complicated advice from above.
You simply measure this with a mouse over sensor.
- It would require to have the same logic at each object… which is no big deal as you created copies anyway.
- It tells the object when the mouse cursor is over the the object the sensor belongs to. The object is always the owner of the keyboard sensor
- But currently this method becomes very slow with a lot of objects.
A faster method is the use of a single mouse over any sensor
- It allows to find any object the mouse cursor is over
- It can be applied to any object so you can have a separate “object detector”
- It finds ALL objects the mouse cursor is over. Which means you need to filter the detected objects (hitObject )
- It uses exactly one ray which makes it faster than multiply mouse over sensors.
You can filter the hitObject by name (assuming you want to detect added objects of the same original only) or by existing property or by a specific value in a property…
if hitObject.name == specificName: if specificPropertyName in hitObject: if hitObject.get(specificPropertyName == specificValue: ...
The usual question in a game is: WHAT happens WHEN?
You answered the WHEN (mouse over) now the WHAT:
WHAT do you want to do with the hitObject you found?
I feel kinda silly:o . This is what I was trying to do. I guess I figured I had to approach it differently.