How to detect the precise moment a KinematicBody steps off a platform

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


I want to make my character automatically jump when hitting the edge of a platform like in The Legend of Zelda: Ocarina of Time, but I can’t figure out a way to detect the precise moment when the player steps off the platform; if I use “if not is_on_floor()” in _physics_process() to trigger the jumping state, then the jumping state will be continuously triggered when the player is supposed to be falling. I need to trigger the jumping state only once when the player leaves the platform.

Accidently posted my Answer in the Comments, My Apolagies

Nickyroo | 2023-06-03 21:03

:bust_in_silhouette: Reply From: aidave

You’ll need to store more data, for example a flag like was_on_floor, that remembers what is_on_floor() was before this frame.

When was_on_floor is true and is_on_floor() is false then do the autojump.

Save was_on_floor = is_on_floor() at the end of the process function.

Thank you for your answer! Unfortunately, I tried this and it didn’t work, so I set it to continuously print the value of was_on_floor while is_on_floor() is false, and it came back false every time, rather than true the first time and false thereafter, like I would have expected. I made sure that assignment of was_on_floor to is_on_floor() came after that if statement was activated, and I’m not sure what else to try at this point.

enceladus | 2023-06-03 17:00

They have to be in the same function:

var was_on_floor = false;

func _physics_process(delta):
   if was_on_floor and not is_on_floor():
   was_on_floor = is_on_floor() 

aidave | 2023-06-03 20:10

Well that was a waste of my time

aidave | 2023-06-06 13:53

:bust_in_silhouette: Reply From: stormreaver

I don’t know what I’m talking about, but I’m going to offer an opinion anyway (This is The Way):

You can place a raycast on the character at the precise point where you know the character will lose contact with a platform when moving. Keep track of the contact state of the raycast, and when it no longer contacts the platform, invoke the jump.

:bust_in_silhouette: Reply From: Nickyroo

Have a variable named ReachedEdge = false

If the GroundRaycast == null AND ReachedEdge == false, Proceed to Trigger the Jump, AND THEN AFTER that you have triggered the Jump… Set ReachedEdge = true, Until you land again

Its a simple and Effective Cycle for AutoJumping off a ledge

This seems to be working, except that when autojumping, I only seem to jump about half as high as when I hit the spacebar. Not sure why that is (I checked that it’s not registering a jump twice when I hit the spacebar) but I seem to be on the right track with this solution!

enceladus | 2023-06-05 20:15

Glad to hear its leading to the right track!.. Regarding your Issue with only jumping half height on a normal User-Inputted Jump… Its possible that the issue could take place due to how you have your Character to move

I would reccomend having your player jump with a “* delta” and also Multiplied by the User’s Monitor Refresh Rate… Whenever I have had issues with Choppy Movement or un-reliable Jumps, I was able to fix them using the multiplication of these two features!

I assume you already have used “delta”

Nickyroo | 2023-06-06 01:21

I figured out what the issue was! It WAS registering a jump twice when I hit the spacebar, but not because of a duplicate keystroke; jumping with the spacebar was triggering the reached_edge condition. I’ve added a second floor raycast behind the center of the player model and added the condition that FloorRayCast2 be colliding in order for a jump to take place. It’s still a bit buggy, but it works now!

Edit: after adding three more secondary floor raycasts to cover all directions and making the central raycast extend a little bit further than the rest (to keep the player from autojumping when walking on sloped surfaces), it seems to be working absolutely flawlessly!

enceladus | 2023-06-06 02:59