In my scene, I have a high platform the user can step off of and fall back to the ground. I want to detect the fall.
I’ve been trying to accomplish this by placing an invisible mesh just below the platform (and larger than in), so when the user walks off the platform, they fall through the mesh. However, I can’t seem to get the ActionManager to fire. I’ve played with just about every variable I can think of – size of the camera ellipsoid, adding a “collider” object (of various sizes) to the camera, flipping “checkCollisions” on and off, etc.
Here’s a fairly minimal example. I didn’t include the platform, I just set the camera high enough so it falls through the semi-transparent blue “detector” mesh (which does not, in fact, get detected).
Any ideas? Is movement due to gravity just too fast to detect collision, or excluded from the detection somehow?
Or maybe some code like this, where the camSensor is a mesh attached to, in my case, the camera, and the triggers are the meshes that you pass through :
camSensor.actionManager = new BABYLON.ActionManager(myScene);
let inAction0 = new BABYLON.ExecuteCodeAction(
{trigger: BABYLON.ActionManager.OnIntersectionEnterTrigger, parameter: {mesh: allTriggers[0]}},
(evt) => {
console.log(“entered0”);
theSounds.play(0, 34.5, 2.7);
);
let outAction0 = new BABYLON.ExecuteCodeAction(
{trigger: BABYLON.ActionManager.OnIntersectionExitTrigger, parameter: { mesh: allTriggers[0]}
},
(evt) => {
console.log(“left0”);
var aRand0 = Math.floor(Math.random() * 9);
theSounds.play(0,soundArray[aRand0][0], soundArray[aRand0][1]);
//llTriggers[0].setEnabled(false);
}
);
Thanks! I had not seen the first example, but it’s polling for the interpolation on each render, which I’d want to avoid if possible. The second example was basically what I was doing.
I think I figured it out…
I noticed that certain combinations of the initial camera Y position, and Y position and height of the trigger mesh (the one I fall through) and the camera’s detector mesh worked. But it seemed fairly random whether it would work, rather than at specific ratios.
This led me to think that gravity’s effects on a mesh’s position are quantized in BabylonJS. If a mesh is moving “too fast,” it never “intersects” with the other mesh – it’s on one side in one frame, and on the other side in the next frame.
I did some console logging of each frame, and sure enough, my camera jumps straight from one side of the trigger mesh to the other:
I also see two other surprises with how gravity is implemented, which should be explained better in the docs:
Gravity in BabylonJS represents a velocity, not an acceleration factor as the documentation states (meshes fall at a constant speed, not speeding up as they fall).
This gravitational factor is being applied to every frame, so if 1u = 1m, the default of (0, -9.807, 0) isn’t -9.8m/s, it’s more like 30-60x that, depending on your frame rate. That means it’s both way too fast, and is variable from one machine to another.
The “good” news with (1) and (2) above is that the precise location of each mesh in each frame is known ahead of time, which means you can predict if an intersection will be detected by just playing out the math of (position.y - scene.gravity.y) for each frame from a starting position.
So, I think that the only real solution is to carefully choose a combination of starting position, detector mesh height, gravitational factor, and trigger mesh height that will result in an intersection on the way down. That’s fine for my use case, but for someone working with more complex scenes, that doesn’t sound like fun.