[SOLVED] BetterCharacterControls collide with each other

Hi monkeys, I have a question how to implement the physics in my game.
Untill now I used the BetterCharacterControl for my player controlled character and other NPC’s. The problem is that those CapsuleCollisionShapes of the BetterCharacterControls are colliding with each other, and pushing each other around, what I don’t want obviously. The character and NPC’s should collide with the world/level, But not with each other.
I read in the wiki about collisiongroups - shapes of different groups don’t collide - but then I need to put each NPC in a different group which is not feasable. I also don’t see a method to set the collision group on a BetterCharacterControl.

I think there will be a better and much simpler solution for my case. But I can’t seem to find it. Hope you guys can help!

A solution might be to give the character and the NPCs mesh collision shapes (such as HullCollisionShape) and for the world/level to have a non-mesh collision shape (such as CompoundCollisionShape). But that seems like a lot of extra effort, and it’s likely to run slowly in case you have many NPCs.

1 Like

I didn’t really solve my problem, but found a way around it. The problem was that characters where bumping into each other, and pushing the other characters around.

Problem:

What I did now, is actually check for collisions between 2 collision shapes, and check if it are 2 characters colliding. When this check is true, I stop the movement of the moving character and warp them back a bit so they stop colliding. Since I am using the awesome Zay-es entity component system, this was actually quiet simple, since I only needed to remove the ‘DestinationComponent’ from the entity.

@Override
public void collision(PhysicsCollisionEvent event) {
    MovementControl a = event.getNodeA().getControl(MovementControl.class);
    MovementControl b = event.getNodeB().getControl(MovementControl.class);
    if (a != null && b != null) {
        // 2 characters collided
        if (a.isMoving()) {
            // stop and step back a bit
            Vector3f backwards = a.getSpatial().getWorldRotation().mult(Vector3f.UNIT_Z).normalizeLocal().negateLocal().multLocal(0.1f);
            Vector3f newLocation = a.getBasicCharacterControl().getLocation().add(backwards);
            a.getBasicCharacterControl().halt();
            a.getBasicCharacterControl().warp(newLocation);
            EventBus.INSTANCE.publish(new DestinationReachedEvent(a.getEntityId()));
        } else if (b.isMoving()) {
            Vector3f backwards = b.getSpatial().getWorldRotation().mult(Vector3f.UNIT_Z).normalizeLocal().negateLocal().multLocal(0.1f);
            Vector3f newLocation = b.getBasicCharacterControl().getLocation().add(backwards);
            b.getBasicCharacterControl().halt();
            b.getBasicCharacterControl().warp(newLocation);
            EventBus.INSTANCE.publish(new DestinationReachedEvent(b.getEntityId()));
        }
    }
}

The method that handles the event for completeness:

@Override
public void onEvent(DestinationReachedEvent destinationReachedEvent) {
    getEntityData().removeComponent(destinationReachedEvent.getEntityId(), DestinationComponent.class);
}

solved:

I am not saying this is a great or good solution, but it fixes my problem for now.

2 Likes