I am creating a demo game with the book Building a 3d Game with Libgdx. Gravity seems not to be working at all, so I draw debug line with debugDrawer but character's debug lines are also not showing.
Floor's debug lines are showing properly, also character is added to world as I have checked collisionObjects count.
Here is my running game: (can't post picture directly as its my first post ;P)
My characater creation code is:
private static Entity createCharacter(BulletSystem bulletSystem, float x, float y, float z) {
Entity entity = new Entity();
ModelComponent modelComponent = new ModelComponent(playerModel, x, y, z);
entity.add(modelComponent);
CharacterComponent characterComponent = new CharacterComponent();
characterComponent.ghostObject = new btPairCachingGhostObject();
characterComponent.ghostObject.setWorldTransform(modelComponent.instance.transform);
characterComponent.ghostShape = new btCapsuleShape(2f, 2f);
characterComponent.ghostObject.setCollisionShape(characterComponent.ghostShape);
characterComponent.ghostObject.setCollisionFlags(btCollisionObject.CollisionFlags.CF_CHARACTER_OBJECT);
characterComponent.characterController = new btKinematicCharacterController(characterComponent.ghostObject,
characterComponent.ghostShape, .35f);
characterComponent.ghostObject.userData = entity;
entity.add(characterComponent);
// add character to bullet world
bulletSystem.collisionWorld.addCollisionObject(characterComponent.ghostObject,
(short) btBroadphaseProxy.CollisionFilterGroups.CharacterFilter,
(short) (btBroadphaseProxy.CollisionFilterGroups.AllFilter));
// It is showing 2 in console.
System.out.println(bulletSystem.collisionWorld.getNumCollisionObjects());
bulletSystem.collisionWorld.addAction(characterComponent.characterController);
return entity;
}
BulletSystem.java
public class BulletSystem extends EntitySystem implements EntityListener {
public final btCollisionConfiguration collisionConfiguration;
public final btCollisionDispatcher dispatcher;
public final btBroadphaseInterface broadphase;
public final btConstraintSolver solver;
public final btDiscreteDynamicsWorld collisionWorld;
private btGhostPairCallback ghostPairCallback;
public int maxSubSteps = 5;
public float fixedTimeStep = 1f / 60f;
@Override
public void addedToEngine(Engine engine) {
engine.addEntityListener(Family.all(BulletComponent.class).get(),
this);
}
public BulletSystem() {
collisionConfiguration = new
btDefaultCollisionConfiguration();
dispatcher = new
btCollisionDispatcher(collisionConfiguration);
broadphase = new btAxisSweep3(new Vector3(-1000, -1000,
-1000), new Vector3(1000, 1000, 1000));
solver = new btSequentialImpulseConstraintSolver();
collisionWorld = new btDiscreteDynamicsWorld(dispatcher,
broadphase, solver, collisionConfiguration);
ghostPairCallback = new btGhostPairCallback();
broadphase.getOverlappingPairCache().
setInternalGhostPairCallback(ghostPairCallback);
this.collisionWorld.setGravity(new Vector3(0, -9f, 0));
}
@Override
public void update(float deltaTime) {
collisionWorld.stepSimulation(deltaTime, maxSubSteps,
fixedTimeStep);
}
}
My GameScreen is
class GameScreen extends ScreenAdapter {
private BulletGame game;
private PerspectiveCamera cam;
private Environment env;
private ModelBatch mb;
private Engine engine;
private BulletSystem bulletSystem;
private Model floor;
private Entity character;
private DebugDrawer debug;
GameScreen(BulletGame bulletGame) {
game = bulletGame;
Bullet.init();
initCamera();
initEnvironemnt();
mb = new ModelBatch();
ModelBuilder modelBuilder = new ModelBuilder();
floor = modelBuilder.createBox(40, 1, 40,
new Material(ColorAttribute.createDiffuse(Color.YELLOW),
ColorAttribute.createSpecular(Color.BLUE),
FloatAttribute.createShininess(16f)),
VertexAttributes.Usage.Position
| VertexAttributes.Usage.Normal);
engine = new Engine();
engine.addSystem(bulletSystem = new BulletSystem()); // WORLD with entity listener
engine.addSystem(new RenderSystem(mb, env)); // renders all MODEL_COMPONENTS
debug = new DebugDrawer();
debug.setDebugMode(btIDebugDraw.DebugDrawModes.DBG_MAX_DEBUG_DRAW_MODE);
bulletSystem.collisionWorld.setDebugDrawer(debug);
addEntities();
}
private void addEntities() {
engine.addEntity(EntityFactory.createStaticEntity(floor,0, 0, 0));
engine.addEntity(character = EntityFactory.createPlayer(bulletSystem, 0,10,15));
}
@Override
public void render(float delta) {
mb.begin(cam);
engine.update(delta);
mb.end();
debug.begin(cam);
bulletSystem.collisionWorld.debugDrawWorld();
debug.end();
}
I was disposing off my screen and thus character collision object the wrong way:
private void setScreen(Screen screen) {
if (screen != null) {
screen.hide();
screen.dispose();
}
this.screen = screen;
if (screen != null) {
screen.show();
screen.resize(Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
}
}
Dispose method in my screen:
public void dispose() {
mb.dispose();
bulletSystem.collisionWorld.removeAction(character.getComponent
(CharacterComponent.class).characterController);
bulletSystem.collisionWorld.removeCollisionObject
(character.getComponent(CharacterComponent.class).ghostObject);
character.getComponent(CharacterComponent.class).characterController.dispose();
character.getComponent(CharacterComponent.class).ghostObject.dispose();
character.getComponent(CharacterComponent.class).ghostShape.dispose();
}
Sticking to the default Game class solved the problem.