利用者:Agoose77/BGE Collision Proposal

提供: wiki
移動先: 案内検索

BGE GameObject Collision API

Every time two objects collide with each other, the callbacks registered on the KX_GameObjects would be called. This includes when two objects stop colliding with each other (removed from narrowphase). The status attribute denotes the entry status of the collision. The rest of the attributes could include impulse, face, material, normal and so on.

Collision API

Adding a collision callback to the KX_GameObject class:

short KX_GameObject::addCollisionCallback(PyObjectPlus callback){
    m_collisionCallbacks.push_back (callback);
    short id = this->assignCollisionID(callback);
    return id;
}

void KX_GameObject::removeCollisionCallback(short id){
    short index = this->getCollisionIndex(id);
    m_collisionCallbacks.erase(index);
}

Collision Object

Whenever the object's collision status changes, it would call this function with the colliding object and the status of collision. See this mock-up KX_CollisionObject

KX_CollisionObject::KX_CollisionObject(KX_GameObject* collider, MTVector3& impulse, bool status){
    m_object(object);
    m_impulse(impulse);
    m_status(status);
    // ...
}

PyAttributeDef KX_CollisionObject::Attributes[] = {
    KX_PYATTRIBUTE_BOOL_RO("status", KX_CollisionObject, m_status),
    KX_PYATTRIBUTE_BOOL_RO("object", KX_CollisionObject, object),
    KX_PYATTRIBUTE_BOOL_RO("impulse", KX_CollisionObject, m_impulse),
    //...

}

Collision Callbacks

This would be passed to the callback as follows:

def collision_callback(collision):
    # Status of collision (start or end)
    status = collision.status
    # Other collider    
    obj = collision.object

    if status:
        print("colliding with {}".format(obj.name))
    else:
        print("separated from {}".format(obj.name))

callback_id = object.addCollisionCallback(collision_callback)
#...
object.removeCollisionCallback(callback_id)

The issue I can foresee is that if the GameObject is deleted before the collision stops, this would raise some error. However, simply defaulting to None or an invalid gameobject reference would be acceptable.