How do you control a player character in Bullet Physics?

10,666

My answer to this question here tells you what worked well for me and apparently also for the person who asked.

Avoid ground collision with Bullet

The character controller implementations in bullet are very "basic" unfortunately. To get good character controller, you'll need to invest this much.

Share:
10,666

Related videos on Youtube

user975989
Author by

user975989

Updated on June 04, 2022

Comments

  • user975989
    user975989 about 2 years

    I am not sure how you are supposed to control a player character in Bullet. The methods that I read were to use the provided btKinematicCharacterController. I also saw methods that use btDynamicCharacterController from the demos. However, in the manual it is stated that kinematic controller has several outstanding issues. Is this still the preferred path? If so, are there any tutorials or documentations for this? All I found are snippets of code from the demo, and the usage of controllers with Ogre, which I do not use.

    If this is not the path that should be tread, then someone point me to the correct solution. I am new to bullet and would like a straightforward, easy solution. What I currently have is hacked together bits of a btKinematicCharacterController.

    This is the code I used to set up the controller:

    playerShape = new btCapsuleShape(0.25, 1);
    ghostObject= new btPairCachingGhostObject();
    ghostObject->setWorldTransform(btTransform(btQuaternion(0,0,0,1),btVector3(0,20,0)));
    physics.getWorld()->getPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
    ghostObject->setCollisionShape(playerShape);
    ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
    controller = new btKinematicCharacterController(ghostObject,playerShape,0.5);
    physics.getWorld()->addCollisionObject(ghostObject,btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
    physics.getWorld()->addAction(controller);
    

    This is the code I use to access the controller's position:

    trans = controller->getGhostObject()->getWorldTransform();
    camPosition.z = trans.getOrigin().z();
    camPosition.y = trans.getOrigin().y()+0.5;
    camPosition.x = trans.getOrigin().x();
    

    The way I control it is through setWalkDirection() and jump() (if canJump() is true).

    The issue right now is that the character spazzes out a little, then drops through the static floor. Clearly this is not intended. Is this due to the lack of a rigid body? How does one integrate that?

    Actually, now it just falls as it should, but then slowly sinks through the floor.

    I have moved this line to be right after the dynamic world is created

    physics.getWorld()->getPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
    

    It is now this:

    broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
    

    I am also using a .bullet file imported from blender, if that is relevant.

    The issue was with the bullet file, which has since been fixed(the collision boxes weren't working). However, I still experience jitteryness, unable to step up occasionally, instant step down from to high a height, and other issues.