Hey,
In the game I’m workin on there is a character who should eat plants which appear in front of him. The character itsel got a RigidControl and a CapsuleCollisionShape attached.
But the character shall not eat the plant when he collide with it, but when the plant is in a specific distance in front of him. I can’t use a ray in this case, beacuse I want to test if the plant is in front of his mouth and not in a line in front of him. So I need something like an invisible box in front of the character with the width of his mouth.
What are my options to check collisions with this “box” and the plants, which are just geometries?
You could use a GhostObject to check for overlaps or if you don’t necessarily want to use physics just do a normal collideWith() check using a BoundingBox.
thanks for the fast reply. If I use the GhostObject, all of my plants must be physic objects, is that right? Isn’t that a bit too much?
I already tested the BoundingBox approach, but it doesn’t work :/.
This is how I instantiate the box and attach it to the mob(the character):
[java] Box box2 = new Box(1f,1f,1f);
Geometry box2b = new Geometry(“Box2”,box2);
mob.attachChild(box2b);
box2b.setLocalTranslation(0f, 0, -3f);
box2b.setModelBound(new BoundingBox());
box2b.updateModelBound();[/java]
Then I do this in the prePhysicsTick of the RigidbodyControl of the character:
[java] CollisionResults results = new CollisionResults();
(food).collideWith(mouth.getModelBound(), results);
if (results.size() != 0) {
for (int i = 0; i < results.size(); i++) {
CollisionResult col = results.getCollision(i);
Geometry plantGeo = col.getGeometry();
status.hungerDecrease();
food.detachChild(plantGeo.getParent().getParent());
}
}
}[/java]
But results is alway 0. food is a Node which got all foodGeometries attached. mouth is the box. What have I done wrong? I also read that BoundingBox's doesn't rotate with the geometrie, what does that mean in my case? The character can rotate and the box always must be in front of its mouth.
Just make it a sphere, then it doesn’t need to rotate. Also yeah, anything you want to interact with has to be physics enabled, but you have to have some collision information anyway, collideWith() also creates a collision dataset… Another option is just to check the locations of the objects and see if they are in front of the mouth.
Also read the collision tutorials, it works like rootNode.collideWith(boundingBox);
So what did I wrong in the code I posted?
Your for loop looks strange.
It wasn’t copied right. I corrected it. However, results.size is always 0, even if the box collides with the plant(food).
You use the bounding box of the mouth which is at the mouths center, so you basically check the collisions at 0/0/0. Create a copy or translate the bounding box to the location using mouth.getModelBound().translate(newTransform, storeBounding); Also no need to set the bounding box like you do. You could just create one separate from the existing objects to do collision checks.
Thanks :). But I still got one problem. When the colission occurs, I get the error java.lang.IllegalStateException: Scene graph is not properly updated for rendering.
State was changed after rootNode.updateGeometricState() call. Does that mean I can not detach a Child in the prePhysicsTick method and should do it in the update method?
Yep. Enqueue the calls like it was threading (then you can also enable parallel threading and have no issues :)). Its because physics and visual update are actually still separate for flexibility (e.g. some games might want to detach it completely from the visual update loop).
Edit: …but wait, why do you have physics still?
I did the Collision detection on the prePhysicsTick of my characterMovement class which extends RigidBodyControl. The character doesn’t collide with the plants, just eats them, so I don’t wanted to enable physics on them. So I think the collideWith approach is the better one in my case. However, the characterMovement class is propably not a good place to put the plantEat method in, I will change that. Thanks for your help :).
Yeah, the collideWith() stuff is only scenegraph dependent, probably best to untangle that