When is "is_on_floor()" function true excatly?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Paar

Hi. I have a problem with function “is_on_floor()”. My object (KinematicBody2D) is standing still on another object (StaticBody2D) and is being constantly pulled down by the gravity with the function “move_and_slide(velocity, Vector2(0, -1)”. Now, if I print the function “is_on_floor()” every frame I can see that it returns “true” only on every fourth frame (project is locked at 60 fps). Is this correct behaviour?

Debugger:
False
False
False
True
False
False
False
True

_physics_process() is called at fixed intervals, while _process() is called at variable intervals. (I’m not sure how fixing the fps works.) Are you perhaps calling move_and_slide() in the physics processing but the print() statement in normal processing? Maybe something along these lines explains your result.

Diet Estus | 2018-03-20 15:06

Well, I think I have found the problem. First a snippet from my code:

if is_on_floor():
	speed.y = 0

speed.y += GRAVITY * delta
if speed.y > MAX_FALL_SPEED:
	speed.y = MAX_FALL_SPEED

For some reason when the speed.y is reset to 0, the is_on_floor() function stops working properly. I have checked the remaining vector after the reset and it’s (0, 1.666667) with false floor flag. Then it’s (0, 3.333333) for the next frame, again with false floor flag In the third frame it’s (0, 0) with the floor flag set to true. Why is the collision not detected right in the first frame? What’s more, the get_slide_count() always returns 0 even though there is a collision and get_slide_collision(0) returns a null object. Probably a bug.

Paar | 2018-03-20 16:51

:bust_in_silhouette: Reply From: KND2501

is_on_floor rings true depending on your script. Can be every frame or only the first frame or around every other number of frames.

If you have irregular results there might be something going on with collisions, maybe play around with the margins a bit to see what it does.

Why do you want vertical speed on 0 when on the floor?

Thanks for the tip, I will try to play with the margins. I reset the speed to 0 to dial back the fall speed when on a platform so I will start to fall with a normal speed when getting off it.

Paar | 2018-03-20 18:13

OK, so setting the Safe Margin property to 0.001 solved the problem, now the is_on_floor() function returns true all the time. But I am a bit confused about the property. How exactly does it work? Is the value in pixels? I.e. if I set the value 0.5, the engine checks the edge of the object and if it’s 0.5 pixel away from another object, it detects collision?

Paar | 2018-03-20 20:06

Í figured the value might cause you to float mid-air after you touched the floor giving the appearance of being on the floor while hoovering just above it, or something of that nature.

Actually i’m not sure what it uses, the lowest number you can input is 0,001 so i’m going to assume it’s not based on pixels.

But collisions can be a bit fiddly, especially if you want to do pixel perfect scenes, so be sure to check em if things seem to respond in unusual ways.

KND2501 | 2018-03-20 20:58

The weird thing is, both setting it to 0,001 or 100 fixed it sometimes thinking it’s in the air for me. The problem was at the default value.

CoverEye | 2018-12-09 00:39