There is indeed no explicit code that checks for collisions in example “physics_3d_collision_layers (or other physics examples). The point of physics engine is that such collisions are checked internally by CGE code (actually our physics engine, Kraft). Also internally we “react” to them (when 2 objects collide, they bounce off each other, by default). So there’s just no code needed to do this. It happens just because you set up TCastleRigidBody and TCastleXxxCollider instances.
See Physics | Manual | Castle Game Engine for more docs about physics.
As for your question: you want to detect whether player is standing on the ground. To do this, use “ray cast” with a ray direction set to “downward” (this is Vector3(0, -1, 0)
in CGE). If you have an instance of TCastleRigidBody
called MyRigidBody
, do something like
var
GroundRayCast: TPhysicsRayCastResult;
RayOrigin: TVector3;
MaxDistanceToGround: Single;
StandOnGround: Boolean;
begin
RayOrigin := ...;
MaxDistanceToGround := ...;
GroundRayCast := MyRigidBody.PhysicsRayCast(
RayOrigin,
Vector3(0, -1, 0),
MaxDistanceToGround
);
StandOnGround := GroundRayCast.Hit and (GroundRayCastHit.Distance <= 1.23 + 0.01);
if StandOnGround then
... // do some decision based on StandOnGround, or pass it somewhere
end;
Set RayOrigin
to some point in the middle of the avatar. Like just Vector3(0, 1.23, 0)
, where 1.23
is just an example. If the raycast will return that something collides with a distance similar to 1.23 (you can add there some epsilon like 0.01), then you know you stand on ground. Otherwise (if the raycast returns no collision, or the collision is further than that distance) you know you’re flying the air.
Set MaxDistanceToGround
to some value further than any ground you hope to detect. You can pass just some huge value, like 100000, but actually passing something “significantly larger than the distance you hope to detect” is better. In the example above, I would use 2 * 1.23
, since we don’t care to detect objects further than that.
See Castle Game Engine: CastleTransform: Class TCastleRigidBody for detailed docs of TCastleRigidBody.PhysicsRayCast
.
There’s also Viewport.Items.PhysicsRayCast
, but it’s less comfortable in this case. (because TCastleRigidBody.PhysicsRayCast
automatically ignores collision with parent body, so the ray cast will not detect the avatar). Though if you use layers to already avoid that, then it may also be useful. See Castle Game Engine: CastleTransform: Class TCastleAbstractRootTransform .
See examples/platformer/
for a big example using this technique. It is using PhysicsRayCast
for various purposes, proper jumping being just one of them.