# How to detect that camera is not falling?

**URL:** <https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330>\
**Category:** Questions\
**Created:** [July 7, 2019, 9:54am UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330 "2019-07-07T09:54:15Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![splash27](https://avatars.discourse-cdn.com/v4/letter/s/76d3ee/32.png) [@splash27](https://forum.babylonjs.com/u/splash27)\
**Post date:** [July 7, 2019, 9:54am UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/1 "2019-07-07T09:54:15Z")

</div>

Hi all,

Found a bug in one of my previous demos: [https://www.babylonjs-playground.com/#3CPL8T#1](https://www.babylonjs-playground.com/#3CPL8T#1)  
If we will click spacebar quickly the avatar will jump higher and higher. This happens because I drop `this.jumping` flag on key up event. See line 135.

Actually I need to drop it when camera will be on the ground. One obvious solution is to check inside of onCollide event if collided mesh is a “ground” and then drop the flag. But it’s not universal. What if I land on any other mesh that actually is not a “ground”? Is there a way to check that camera has stopped falling?

---

<div class="post-metadata">

**Author:** ![Abdullah\_Alkawatrah](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/abdullah_alkawatrah/32/3228_2.png) [@Abdullah\_Alkawatrah](https://forum.babylonjs.com/u/Abdullah_Alkawatrah)\
**Post date:** [July 7, 2019, 10:42am UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/2 "2019-07-07T10:42:20Z")

</div>

Hi @splash27,  
I think I had a similar issue with player camera falling off of a building. I found some suggestion about using a ray that points to -Y, and then check the distance with the first picked mesh (or you can set the length of the ray when you define it). I used and it works perfectly.  
Hope this helps.  
Abdullah.

---

<div class="post-metadata">

**Author:** ![splash27](https://avatars.discourse-cdn.com/v4/letter/s/76d3ee/32.png) [@splash27](https://forum.babylonjs.com/u/splash27)\
**Post date:** [July 13, 2019, 9:19pm UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/3 "2019-07-13T21:19:16Z")

</div>

@Abdullah_Alkawatrah,  
Thank you!

But how did you cast the ray?

Did you cast a new ray each time inside onCollide event or when camera moves?  
Or did you create a ray once and change only it’s origin inside onCollide event or when camera moves?  
Or did you find a way to set camera as “parent” for ray?

I am just looking for the most optimized solution.

---

<div class="post-metadata">

**Author:** ![Abdullah\_Alkawatrah](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/abdullah_alkawatrah/32/3228_2.png) [@Abdullah\_Alkawatrah](https://forum.babylonjs.com/u/Abdullah_Alkawatrah)\
**Post date:** [July 13, 2019, 9:42pm UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/4 "2019-07-13T21:42:30Z")

</div>

I am not sure if the below is clear enough. I call this in the renderloop. I found using a dummy box hidden below the camera (bottomBox) as the origin of the ray easier to implement. The dummy box is updated with the camera position to create a new ray.  
This will actually check if the camera (bottombox) is above and in contact with any mesh.

castRay() {  
var origin = this.bottomBox.position;  
var forward = new BABYLON.Vector3(0, -1, 0);  
forward = this.vecToLocal(forward);  
var direction = forward.subtract(origin);  
direction = BABYLON.Vector3.Normalize(direction);  
var length = 30;  
var ray = new BABYLON.Ray(origin, direction, length);  
var hit = this.scene.pickWithRay(ray, (mesh) =\> {  
if (mesh.name != “bottomBox”)  
return true;  
return false;  
});  
if (hit.pickedMesh) {  
// console.log(hit.pickedMesh.name);  
this.canJump = true;  
}  
else {  
this.canJump = false;  
}  
}

---

<div class="post-metadata">

**Author:** ![splash27](https://avatars.discourse-cdn.com/v4/letter/s/76d3ee/32.png) [@splash27](https://forum.babylonjs.com/u/splash27)\
**Post date:** [July 14, 2019, 11:12am UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/5 "2019-07-14T11:12:51Z")

</div>

@Abdullah_Alkawatrah, your solution is interesting, but it still doesn’t work good for me.  
[https://www.babylonjs-playground.com/#WECN4N](https://www.babylonjs-playground.com/#WECN4N)

Problem 1:  
Actor jumps now only when I release button. Not on keydown as it was before.  
I had to add additional flag check (`jumpBtnPressed` at line 229) to fix that. But I feel that this is wrong. One flag should be enough. Probably problem is somewhere else in my code.

Problem 2: If I will be quick enough, I still can do at least double-jump. Despite I set length of the ray very carefully and the jump animation takes only 20 frames.

I afraid that there might be some kind of race condition between checkInputs call and onBeforeRenderObservable call inside of BABYLON. Not sure though.

---

<div class="post-metadata">

**Author:** ![Abdullah\_Alkawatrah](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/abdullah_alkawatrah/32/3228_2.png) [@Abdullah\_Alkawatrah](https://forum.babylonjs.com/u/Abdullah_Alkawatrah)\
**Post date:** [July 14, 2019, 11:25am UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/6 "2019-07-14T11:25:15Z")

</div>

@splash27, i am using event listeners not camera controls. I am not sure if this makes a difference, I think camera inputs are queued for processing.  
I am using this here: [https://csserver.herokuapp.com/](https://csserver.herokuapp.com/). You can try to climb the ladder and see how you cannot jump midair. Use shift to jump. If you look (point camera to player foots) far down you will see the dummy box, which i think can be removed (I have seen in your playground you are using camera position instead).

---

<div class="post-metadata">

**Author:** ![Abdullah\_Alkawatrah](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/abdullah_alkawatrah/32/3228_2.png) [@Abdullah\_Alkawatrah](https://forum.babylonjs.com/u/Abdullah_Alkawatrah)\
**Post date:** [July 16, 2019, 11:00pm UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/7 "2019-07-16T23:00:02Z")

</div>

@splash27, I found where i got the concept of using ray cast to detect if camera is on top of something.

> [@How to detect avatar is on the ground?](https://forum.babylonjs.com/t/how-to-detect-avatar-is-on-the-ground/516/16):
>
> Ok, I’ve settled with this When I walked off the car my algorithm determined that she was off the ground and automatically enabled flight mode (in reality one could easily step off the car, but I had to make some sacrifices). Then I manually flew (PG-UP and PG-DOWN keys) over the building and when I got close to the roof it automatically turned off flight mode, then when I walked off it turned on flight mode. That’s good enough for now. I’m only use one raycast for this.

---

<div class="post-metadata">

**Author:** ![splash27](https://avatars.discourse-cdn.com/v4/letter/s/76d3ee/32.png) [@splash27](https://forum.babylonjs.com/u/splash27)\
**Post date:** [July 28, 2019, 10:24am UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/8 "2019-07-28T10:24:39Z")

</div>

Well, the only possible solution I found to suppress undesired double jumps is throttling of jump button presses.

[https://www.babylonjs-playground.com/#WECN4N#1](https://www.babylonjs-playground.com/#WECN4N#1)

---

<div class="post-metadata">

**Author:** ![Wingnut](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/wingnut/32/53_2.png) [@Wingnut](https://forum.babylonjs.com/u/Wingnut)\
**Post date:** [July 28, 2019, 11:50am UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/9 "2019-07-28T11:50:12Z")

</div>

Hi guys!

Recently, I did another playground that used simple ray-casting… so now I’m an expert. (not) 🙂

Splash, take a look at [https://www.babylonjs-playground.com/#WECN4N#3](https://www.babylonjs-playground.com/#WECN4N#3) - lines 118-130 area. (I changed all ‘this’ to be ‘camera’… maybe wiser in _this_ situation). 🙂

I also changed jump height from 6, to 16… just to help me test stuff.

Um, I don’t use a target… to derive a direction for the raycast. I just force the direction to be BABYLON.Vector3.Down(). I KNOW your player/cam is around 4.02 above the ground (and same distance above anything the camera/player jumps-onto).

The ‘hit’ object that is returned by the raycast… contains a _.distance_ which we can use. You can watch line 128 @ console… and see that cam never gets higher than 20, so I made my raycast length be 30… long enough to HIT floor even when cam/player is at top of jump-height.

The raycast is not a performance issue, because we just do ONE cast at the beginning of a jump attempt.

Wha-da-ya-think? No more lines 106-109 hassles, eh? (flags-o-many) Abdullah had a pretty good idea, and we just needed to wire it into your system… and see if it works. Once we removed the need for a target, and instead, aimed the raycast straight down below the camera… it became more useful to us.

There MAY BE problems ahead yet (for your app), but maybe not. Perhaps this camera “butt-cast” will work good for ya.

I see, in BUGS… that you are beginning the problems of WHO IS BOSS… physicsImpostor… or animation keys. Maybe keyframe-animating physics objects worked in 3.0, but that is not good. technically, it should never work… as the impostor is the boss of the mesh… and impostors ONLY move when given a physics-approved force. Keyframes… setting non-physics properties… are not a physics-approved force. 🙂 Here’s [your “k-jumper” playground](https://www.babylonjs-playground.com/#EGHC15#3)… but using a physics-approved force in line 57.

Perhaps a smarter way… end the keyframe mesh-animation… with mesh positioned a tiny distance above floor… and right there… either by animation onEnd callback or by an animation event… add the impostor RIGHT THEN. Always remove the impostor before the keyframe animation starts… and always add it again, just after anim ends. That’s more proper, I think.

Possibly soon… you will be talking about camera/player being TOTALLY controlled-by physics forces. I think @givo and someone else… went down that trail… within the last year… and they both went insane. hah. (mostly from trying to keep camera from sliding (downhill) when player stops on inclines)

I hope I have been helpful. Party on!

---

<div class="post-metadata">

**Author:** ![splash27](https://avatars.discourse-cdn.com/v4/letter/s/76d3ee/32.png) [@splash27](https://forum.babylonjs.com/u/splash27)\
**Post date:** [July 29, 2019, 7:43pm UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/11 "2019-07-29T19:43:36Z")

</div>

Hi Wingnut,

Your solution looks much simpler and it solves double-jump problem, but it is kind of buggy in some other places.

1. If you will press and hold spacebar until jumping end and then release it you will jump again. That’s weird.
2. If you will press and hold spacebar until jumping end and then will press movement button you will jump.

I am not a binary flag maniac, but I had to use them to suppress all this strange glitches.

_this_ is ok inside keyboardHandler function. Look how I am setting an observer:  
`keyboardObserver = scene.onKeyboardObservable.add(keyboardHandler.bind(camera));`

Maybe it makes my playground a little bit more complex, but it makes a copying from my codebase easier, because I am actually extending FreeCamera by adding my methods.

---

<div class="post-metadata">

**Author:** ![Givo](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/givo/32/4968_2.png) [@Givo](https://forum.babylonjs.com/u/Givo)\
**Post date:** [July 29, 2019, 9:44pm UTC](https://forum.babylonjs.com/t/how-to-detect-that-camera-is-not-falling/4330/12 "2019-07-29T21:44:15Z")

</div>

Yep, that was me. Topic was called SSS (stop sliding on slopes)

I’ve taken a break from coding for the summer, but soon I’m gonna push myself to start making NYNS for real. I’ll steam it at [twitch.tv/GivoGames](http://twitch.tv/GivoGames) so I can’t watch youtube if I get frustrated.
