Hello!
Those who've seen my posts know I've been kept busy with a "player model that follows terrain and is affected by gravity and collisions". Was almost happy with my PhysicBox-made player, until I played with TerrainBlocks this morning. Stairs were also a problem
So, background:
You have a player physical representation and would like it to:
- fall when there's nothing under its "feet"
- climb hills (PhysicBox -in my attempts- kept bouncing against hills or sliding back even from minor hills, was slow to move on the most minor hills, etc.)
- climb stairs
- define a "step height" to avoid jumping walls
So, here's my first working attempt, which seems to please me… of course, I'm very inexperienced so there's plenty of room for upgrade, suggestion, etc.
I hope it helps!
// This ray is aimed downwards to find a ground
ray = new Ray(body.getLocalTranslation(), new Vector3f(0, -1, 0));
PickResults results = new TrianglePickResults();
results.setCheckDistance(true);
rootNode.findPick(ray, results);
if (results.getNumber() > 0) {
closest = results.getPickData(0);
// The body "floats" above the ground, so it may climb stairs and easy hills
if (closest.getDistance() <= 0.50f) {
// Disable gravity to avoid shaking of your body
body.setAffectedByGravity(false);
// Cancel "parasite" forces that also causes this shaking
body.clearDynamics();
// Get the closest solid item
Geometry geom = closest.getTargetMesh().getParentGeom();
// The physical body is set its height at .45f above that surface
// note: the legs are not meant to "block" when they hit something
// note2: this height is a "step max height, you won't climb things that are too high
newHeight = geom.getWorldTranslation().y + 0.45f;
// Terrainblocks were my initial problem, could not move a PhysicsBox over a hill, etc.
// Recover the height "under your feet" of the terrainblock (I've tested with a heightmap based terrainblock)
if (geom instanceof TerrainBlock) {
// This adds the delta between the "zero level" and the height "under your feet" to the new height
newHeight += ((TerrainBlock) geom).getHeight(body
.getLocalTranslation());
}
// Assign the new height to your body
body.getLocalTranslation().y = newHeight;
}
// Higher than your "leg height"? Enable gravity until you get to less than this height.
else {
body.setAffectedByGravity(true);
}
// No pick result? Hmm, you're falling in the void!
} else {
body.setAffectedByGravity(true);
}
Future modifications imply:
- compare the height between the actual position and the candidate position (to improve step height)
- jump handling (add force, re-enable gravity, etc.)
- better approach of the "ghost legs"