How to solve weird "jump" timings

Godot Version

v4.2.2

Question

Hello guys. I’m very new in godot, just started few weeks ago. I came from unity, but in general I’m quite new in game dev. Currently I’m working on my first 2d game in godot 4 using gdscript (I’m rewritting that from unity), something similar to Super Mario.
My problem is quite unintuitive, I feel like godot is insanely less “forgivable” than unity when it comes to timings on pressing buttons. I feel like I need to be ultra perfectly in time when I press jump button (using Input.is_action_just_pressed("jump")), otherwise my character just skips the jump. It’s very visible when I run to the end of the edge and need to jump or I need to do jump just after landing. Precisely I feel like the time period in which I need to press this button is significantly shorter than it used to be in unity. Now unity seems to give slightly more time to press the button. It’s quite difficult to explain that in other way actually. Is it possible that my movement script is just wrong or it’s badly optimized, or it’s “normal” here in godot? However I don’t use anything else, but just modified version of basic script that comes with CharacterBody2D.

I don’t really know if that’s gonna help but I’ll put some simplified version of the logic below (I am skipping all the stuff that doesn’t matter in this case).

Player.gd

func _ready():
	player_movement.init(self)

func _physics_process(delta):
	player_movement.process_movement(delta)

PlayerMovement.gd

func process_movement(delta: float):
        if !active: 
		return
	__handle_jump_and_fall(delta)
        var direction = Input.get_axis("move_left", "move_right")
	__flip_player(direction)
	__apply_animations(direction)
	__move_character(direction)
        player.move_and_slide()
func __handle_jump_and_fall(delta: float):
	if Input.is_action_just_pressed("jump") and __can_jump():
		player.velocity.y = __get_jump_velocity()

It’s not that clear to me what you’re talking about. Are you referring to the time interval in which a jump input is valid, or is your input not registering?

I’m going to go ahead and assume that your input is not registering (based off of the facts presented). The reason your input is sometimes not registered is because you’re assuming that Godot works the same way Unity does; by checking your input in the _physics_process() (Unity equivalent is FixedUpdate()). This is simply not the case. From Godot Docs on the usage of _process() and _physics_process():

[…] one should avoid making input checks during these callbacks. _process() and _physics_process() will trigger at every opportunity (they do not “rest” by default). In contrast, *_input() callbacks will trigger only on frames in which the engine has actually detected the input.

In other words, you should use _input() or _unhandled_input() when working with, well input. You can use _process() to continously detect input (e.g. when you need to get movement input for your player character). However, _physics_process() is not suited for the purpose of detecting input because it doesn’t run every frame. This is, presumably, the reason for your issue: using _physics_process() to detect input.

Here are your options:

  • Use _input() for handling your input logic
  • Use _process() for handling your input logic

NOTE
As a beginner (switching from Unity), it may not be immediately obvious that _input() is given the input event as a parameter. This event-parameter should be used. See the documentation’s section on input handling for usage examples.


Hopefully I have given you the right answer. If I misunderstood something, please describe your issue in more detail.

1 Like

Wow, thank you very much for your answer. Of course you’re right - I thought that I should handle input in _physics_process(). I changed that to the way that you suggested and I already noticed a significant progress!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.