A question about collision and objects list in python

I’m having problems with a specific task I want to make.
I have a sensor that detects several objects. I have a python script for it and it works.

if collision.positive:
        
        objects_list = collision.hitObjectList
        
        if objects_list:
            
            for obj in objects_list:
                
                obj.scene.addObject('BOX', obj, 0)
                obj.endObject()

This is just an example of the script I’m using.
Is there a way to differentiate objects in the objects list?
For example this collision works that it detects the same property.
I want for example for the script to detect two or more objects like BOX, ITEM1 and ITEM2.
And then set the object BOX to be the parent of ITEM1 and ITEM2.

Also, is there a way how to detect a negative collision in python like when I invert the collision sensor in logic bricks?

Ok so I have this script which seems to work but I don’t know how to set the object’s parent

if collision.positive:
        
        objects_list = collision.hitObjectList
        
        if objects_list:
            
            for obj in objects_list:
                
                if obj.name == 'SPAWNER':
                    added_object = obj.scene.addObject('ITEM1', obj, 0)
                    added_object.setParent(obj.name('BOX'))
                    obj.endObject()

If anybody knows how to write it correctly.
I want to use specific objects from an object list. These objects have the same property and I want to give them specific tasks when the collision occurs.

if "propname" in obj: #object has property with that name

Usually a bit more comfortable than checking by object name. Value and type of the property itself don’t really matter as far as the evaluation is concerned, it only cares about whether a property with the given name exists.

if "BOX" in obj:          #object belongs to the box family

    if   obj["BOX"] == 0: #logic for box type A
    elif obj["BOX"] == 1: #logic for box type B
    else:                 #logic for box type C

Parenting is just a function call: setParent()


You want to know when you’re no longer colliding?

# add a generic prop to remember whether weve hit something
if "lastcol" not in obj: obj["lastcol"] = None;

# assign last object in collider list to this generic property
if collision.positive: obj["lastcol"] = collision.hitObject;

# if no collision detected & lastcol != None
elif obj["lastcol"]:
    #do the one-time "no longer colliding" stuff here
    obj["lastcol"] = None;

In any case, if not collision.positive would evaluate to true anytime the sensor doesn’t send a pulse. However, if this sensor is the only one that activates the python controller you’d need to connect an additional sensor in order for the script to run – no pulse, no fun.

1 Like

Thank you for the info. I’ll test it out later when I’ll get the chance.
If I want the parent to be a specific object in the object list, what should I write?

setParent(obj["BOX"])

Something like this?
Because I thought that this would be the object’s property and not the object itself.
I would like to know how to write the individual objects in the object list.

BOX as I used it is simply a property name for an integer, not an object reference.

You read the API, so you know you need an object reference. An integer is not an object reference, neither is obj.name(). Maybe, just maybe, scene.objects[object_name] is more like it, eh?

Well, how do you know that the object is in the list? Have you checked? Then save a reference.

par = None;
for obj in object_list:
    if "prop" in obj:
        par = obj; break;

But now you have another problem. You have to loop twice. So do that.

for obj in object_list:
    if "prop" not in obj and par: obj.setParent(par);
1 Like

Thank you, the object will be always present.

Thank you for your help. Parenting the object works as I wanted.
But when I have multiple objects in the loop, it targets just one and not all of them.
The script I have:

objects_list = collision.hitObjectList
        
        if objects_list:
            
            par = None;
            for obj in objects_list:
                if "BOX" in obj:
                    par = obj; break;
            
            for obj in objects_list:
                if "BOX" not in obj and par: obj.setParent(par);
            
            for obj in objects_list:
                spawn = obj.children['BOX-NoCOL']
                
                if "ITEM" in spawn:
                    if   spawn["ITEM"] == 0:
                        added_object = spawn.scene.addObject('BOX_RIG', spawn, 0)
                        added_object.setParent(par)
                        spawn.endObject()

I wanted to target the object’s children by its property but that didn’t work unless I added its name.
This works, but it will target just one copy of the children and not all of them.

for child in obj.children:
    child.doWhatever();

# for grandchildren (children objects of children objects)
for child in obj.childrenRecursive:
    child.doSomething();
1 Like

Thank you, it seems it works perfectly.