Manual collision response for kinematic objects
Posted: Wed May 12, 2021 12:58 pm
Hey guys, I just started using bullet (BulletSharp for C#) and I really like it! The automatic collisions response is awesome. But now, I want to add some custom character behaviour and need your help:
I have a kinematic character object (box shape) that gets created with the following settings:
I then add both the _rigidBody and the _ghostObject to my current world.
I move my object around with this method:
My problem now is this:
I use the ghost object to detect collisions with other objects:
This kind of works but my kinematic object does not stop when it hits a different object. It kind of moves slightly into it (before the colliding object responds to my kinematic player object).
What I would like my kinematic player object to behave like is:
I have a kinematic character object (box shape) that gets created with the following settings:
Code: Select all
// ...
_rigidBody.ActivationState = ActivationState.ActiveTag | ActivationState.DisableDeactivation;
_rigidBody.CollisionFlags = CollisionFlags.CharacterObject | CollisionFlags.KinematicObject;
// create ghost object for it:
_ghostObject = new GhostObject();
_ghostObject.CollisionShape = _rigidBody.CollisionShape;
_ghostObject.WorldTransform = _rigidBody.WorldTransform;
I move my object around with this method:
Code: Select all
public void MoveKinematic(float x, float y, float z)
{
BulletSharp.Math.Matrix newTransform = _rigidBody.MotionState.WorldTransform;
newTransform.Origin += new BulletSharp.Math.Vector3(x, y, z);
_rigidBody.MotionState.WorldTransform = newTransform;
// update the ghost's position as well:
if (HasGhostObject)
_ghostObject.WorldTransform = newTransform;
}
I use the ghost object to detect collisions with other objects:
Code: Select all
// the ghost always collides with the kinematic object
//(since they share the same shape and world transform).
// thus, count must be > 1 whenever the ghost collides with an object other than the player object:
if (_ghostObject.OverlappingPairs.Count > 1)
{
AlignedCollisionObjectArray collisions = GetGhostObject().OverlappingPairs;
foreach(CollisionObject b in collisions)
{
b.Activate(true);
// TODO: Undo the collision by moving the player object back by a bit
}
}
What I would like my kinematic player object to behave like is:
- Check for collisions (ok, works)
- Check by how much it is "inside" another object (minimum translation vector in order to undo the collision)
- Move itself out of the colliding object