Here is simple code of how to check is a character on the ground.
Code: Select all
@Override
public void updateAction(CollisionWorld collisionWorld, float deltaTime) {
this.deltaTime=deltaTime;
world=collisionWorld;
Step();
}
private void Step()
{
CheckGround();
if(!onGround)
{
Gravity();
}
}
private void CheckGround()
{
System.out.println();
Vector3 from = new Vector3(GetCurrentPosition());
Vector3 to = new Vector3(from);
to.y-=(trueHalfHeight+rayLength+Math.abs(currentGravitySpeed.y));
toWorld=new Vector3(to);
ClosestRayResultCallback callback = new ClosestRayResultCallback(from, to);
callback.collisionFilterGroup=MyCollisionFlags.RAY;
callback.collisionFilterMask=(MyCollisionFlags.TERRAIN | MyCollisionFlags.STATIC_OBJ);
world.rayTest(from, to, callback);
if(callback.hasHit())
{
System.out.println("Has hit! " + " hit point: "+callback.hitPointWorld);
lastNormal=new Vector3(callback.hitNormalWorld);
Vector3 newPos = new Vector3(callback.hitPointWorld);
newPos.y+=(trueHalfHeight);
onGround=true;
currentGravitySpeed.clr();
SetPosition(newPos);
}
else
{
System.out.println("Has not hit =(!");
onGround=false;
}
System.out.println("From: "+from+" To: "+to+" length: "+new Vector3(from).sub(to).len());
System.out.println();
}
private void Gravity()
{
Vector3 tmp = new Vector3(GetCurrentPosition());
tmp.add(currentGravitySpeed);
currentGravitySpeed.add(gravity.scl(deltaTime));
SetPosition(tmp);
}
On a flat surface or on a slope of cube it works perfectly, but on a slope of terrain it gives no hit sometimes.
Here a video. Blue line is the ray. So you can see that his length is enough to make a hit, but it does not.
https://youtu.be/tMJ98_rElgQ