Issue regarding Generated moving platforms(tilemap) and Player jump behaviour

Godot Version

4.2.2

Question

In my game, the generated platforms move downwards. When the player is on the floor of these platform, he bounces back and forth on the moving, since the platform first move downwards (here the player is still in the air so it look like there is a small space between the floor and player, as seen in gif 2 below.) and then the player moves down due to gravity, Therefore it is not considered to be on the floor and the player dosent jump. Is there a solution for this?

What should happen even if the platform is moving (player can jump on input when on floor):
2024-08-0621-46-42-ezgif.com-video-to-gif-converter

What is happening (Player cannot jump on input when the floor is moving down):
2024-08-0621-46-42-ezgif.com-video-to-gif-converter (1)

The moving platforms are proceduarrly generated scenes made up of tile maps with a physics layer and script just says it to change position.y with a certain speed. The player Code is below :

extends CharacterBody2D


var Speed = 300.0
var direction = 1

@export var jump_height : float = 250
@export var jump_time_to_peak : float = 0.45
@export var jump_time_to_descent : float = 0.39

@onready var jump_velocity : float = ((2.0 * jump_height) / jump_time_to_peak) * -1.0
@onready var jump_gravity : float = ((-2.0 * jump_height) / (jump_time_to_peak * jump_time_to_peak)) * -1.0
@onready var fall_gravity : float = ((-2.0 * jump_height) / (jump_time_to_descent * jump_time_to_descent)) * -1.0

@onready var ray_cast_right = $RayCastRight
@onready var ray_cast_left = $RayCastLeft


var wall_stick : bool = false

func _physics_process(delta):
	if ray_cast_right.is_colliding() or ray_cast_left.is_colliding():
		if velocity.y < 0:
			velocity.y = 0
				
		if Input.is_action_just_pressed("Touch") and not is_on_floor():
			if ray_cast_left.is_colliding() or ray_cast_right.is_colliding():
				direction *= -1
				jump()
				
	if ray_cast_right.is_colliding() and is_on_floor():
		direction = -1
		
	if ray_cast_left.is_colliding() and is_on_floor():
		direction = 1
	
	position.x += Speed * direction * delta 

	if not is_on_floor():
		if (ray_cast_left.is_colliding() or ray_cast_right.is_colliding()):
			velocity.y += get_gravity() * 0.15 * delta
		elif (ray_cast_left.is_colliding() or ray_cast_right.is_colliding()) and velocity.y > 0:
			velocity.y += get_gravity() * 0.3 * delta
		else: 
			velocity.y += get_gravity() * delta

	# Handle jump.
	if Input.is_action_just_pressed("Touch") and is_on_floor():
		jump()
	
	move_and_slide()

func get_gravity() -> float:
	return jump_gravity if velocity.y < 0.0 else fall_gravity

func jump():
	velocity.y = jump_velocity

Maybe this method can help: apply_floor_snap ( )

It didnt work. When the platforms are moving, it appears like there a thin air boundry between the player and the floor, due to difference in speed.

maybe do your own is_on_floor-method with a raycast that considers this small gap

I had tried that, made a ray cast pointing downwards and tried to snap it to the floor. The issue is first the plat form moves, before the player catches up. In that moment is_on_floor becomes false. when player catches up (due to gravity being higher than platform speed), is_on_floor becomes true (this disregards the apply_floor_snap too hence why it did not work) for just a split second before becoming false again when platform moves again. therefore it appears as bouncing on the moving platform.

You only want to achieve that the player can jump right? So you can just use the raycast and say if it collides you can jump. Basically saying yourself it is on the floor

1 Like

Yea that worked. Thank You very much.
Also while looking around in the inspector, I found this option:
image
Increasing the snap length solved the small air gap problem.

1 Like

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