When creating a Halloween based-game, I decided to have a ‘candy’ collection system. Using the ‘Hello Collison [9]’ tutorial, I decided to create the game. When I discovered collideWith(), I thought I could use it in my game, so the CapsuleCollisionShape can be used with that, to detect the collision with the candy. The problem is when I set it up, I get errors. I discovered that collideWith() with CapsuleCollisionShape is NOT supported.
Is there a way to use it, or an alternative way (maybe attaching it to a node with a Spatial and use the Spatial with collideWith()?)
Use the ‘Hello Collision [9]’ tutorial as an example please.
[TAKE NOTE I DO NOT HAVE ACCESS TO THE PROJECT RIGHT NOW]
[[TAKE NOTE THIS IS MY FIRST POST]]
The Mesh.collideWith() method is part of the Collidable interface, used to test for collisions with another Collidable (typically a Ray) in your scene visualization (the nodes and meshes attached to your scene’s rootNode).
The Hello Collision tutorial uses a different collision system, the one in the Bullet physics library. Collision events from the Bullet library are reported via the collision() method of the PhysicsCollisionListener interface. CapsuleCollisionShape is part of the Bullet library, so it uses the PhysicsCollisionListener interface, not the Collidable interface.
@jmaasing
I took a look at the Physical Listeners link, and I’m curious how I should use it.
Can someone give an example on ‘Hello Collision [9]’ with the Physical Listeners, preferably when you [the player] touches something else (Spatial maybe?) and when it collides you can print something out?
I can’t try it out right now, but I want someone to confirm it works and how to use it.
(2) Declare HelloCollision to be an implementer of PhysicsCollisionListener:
public class HelloCollision extends SimpleApplication
implements ActionListener, PhysicsCollisionListener {
(3) Declare a field to keep track of the touched object:
GhostControl dangerZone;
(4) Turn on physics debugging, so we can see the touched object:
bulletAppState.setDebugEnabled(true);
(5) Create the touched object, add it to physics space, and specify the listener object:
SphereCollisionShape sphereShape = new SphereCollisionShape(5f);
dangerZone = new GhostControl(sphereShape);
dangerZone.setPhysicsLocation(new Vector3f(30f, 0f, 0f));
bulletAppState.getPhysicsSpace().add(dangerZone);
bulletAppState.getPhysicsSpace().addCollisionListener(this);
(6) Implement the collision hander:
@Override
public void collision(PhysicsCollisionEvent pce) {
PhysicsCollisionObject a = pce.getObjectA();
PhysicsCollisionObject b = pce.getObjectB();
if (a == dangerZone && b == player || a == player && b == dangerZone) {
System.out.println("Player is touching the danger zone!");
}
}
Thank you! It did work! Showing this to me is kinda new, because I never really knew I could work with Collision Shapes in this case, but I have one question.
Is there a possible way to SHOW the collision shape, and in this case, sphereShape.
Can you add on to your code by making it be able to be seen WITHOUT debug, with the color red?
If not, is there a way to make it appear as if it’s showing, but it’s something else? Thanks!
Off-hand, it looks a bit tricky because BetterCharacterControl extends AbstractPhysicsControl instead of PhysicsCollisionObject. As written, BCC doesn’t provide direct access to the PCO. To gain access to the PCO, I think you’d have to extend BCC.
Wait, is there any other way to ‘detect collision’ with BetterCharacterControl that’s more normal than this? I’m fine using this, but I want to know all the ways so I can come up with a decision on which one to use.
I’m not very familiar with BetterCharacterControl, so I don’t know how collision detection is normally handled. As I said above, my first impulse would be to extend BCC to gain access to the PCO. Something like this:
import com.jme3.bullet.collision.PhysicsCollisionObject;
import com.jme3.bullet.control.BetterCharacterControl;
public class MyCharacterControl extends BetterCharacterControl {
public MyCharacterControl(float radius, float height, float mass) {
super(radius, height, mass);
}
PhysicsCollisionObject getPco() {
return rigidBody;
}
}
private MyCharacterControl player;
player = new MyCharacterControl(2f, 6f, 1f);
public void collision(PhysicsCollisionEvent pce) {
PhysicsCollisionObject a = pce.getObjectA();
PhysicsCollisionObject b = pce.getObjectB();
if (a == dangerZone && b == player.getPco() || a == player.getPco() && b == dangerZone) {
System.out.println("Player is touching the danger zone!");
}
}
I guess that’ll do. I’ll might make another thread directly to this question to gather the people who are more experienced with BetterCharacterControl. Thanks for your help!
I currently have an error when I was doing it, everything is fine except one line of code. bulletAppState.getPhysicsSpace().addCollisionListener(this);
It gave me an when run saying: RuntimeException: Uncompilable source code - Erroneous sym type: com.jme3.bullet.PhysicsSpace.addCollisionListener
And when I went with it’s suggestion to be bulletAppState.getPhysicsSpace().addCollisionListener((PhysicsCollisionListener) this);
This error occured: ClassCastException: mygame.Main cannot be cast to com.jme3.bullet.collision.PhysicsCollisionListener