My gravity script seems to be clipping my character into the ground, any tips?

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

I have a script for a simple 2D platformer in Godot 4 here, that I basically just stole from the documentation and altered some stuff. Sadly, it doesn’t work; the character seems to slowly clip into the ground until I can’t move anymore.

extends CharacterBody2D

var walk_speed = 300
var jump_speed = -400

var gravity = 100


func _physics_process(delta):
    # Add the gravity.
    velocity.y += gravity * delta

    # Handle Jump.
    if Input.is_action_just_pressed("Jump") and is_on_floor():
	    velocity.y += jump_speed

    print(global_position)

    # Get the input direction.
    var direction = Input.get_axis("Left", "Right")
    velocity.x = direction * walk_speed

    move_and_slide()

When I run this code, the player character’s y coordinates slowly increase until my character is frozen.

Did you checked the Tilemap ?

There is a difference between godot 4.x and godot3.x in Tilemaps

Try the code in godot 3.x snd see if it works correctly

Zylo_X | 2023-03-29 19:39

:bust_in_silhouette: Reply From: Zylo_X

Hi there :slight_smile:

instead of giving a value to gravity try this # for godot 4.0 and higher

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

for smooth movement try this

extends CharacterBody2D
var Acceleration = 0.25
var Floor_Friction = 0.2
var walk_speed = 300
var jump_speed = -700

var gravity =  ProjectSettings.get_setting("physics/2d/default_gravity")


func _physics_process(delta):
	# Add the gravity.
	velocity.y += gravity * delta

	# Handle Jump.
	if Input.is_action_just_pressed("Jump") and is_on_floor():
		velocity.y += jump_speed

	# Get the input direction.
	var direction = Input.get_axis("Left", "Right")
	velocity.x = direction * walk_speed
	if direction !=0:
		velocity.x = direction*walk_speed
		velocity.x = lerp(velocity.x,direction*walk_speed,Acceleration)
	elif direction ==0:
		velocity.x = lerp(velocity.x,0.0,Floor_Friction)
	move_and_slide()

physics/2d/default_gravity actually made the clipping worse, because the default gravity was 960 and I used 100 in my code.

Energia | 2023-03-28 23:44

:bust_in_silhouette: Reply From: DivinePart
var walk_speed = 300
var jump_speed = -400

var gravity = 100
# var gravity =  ProjectSettings.get_setting("physics/2d/default_gravity")


func _physics_process(delta):

    # "Add the gravity only and only if character is in air."
    if not is_on_floor():
        velocity.y += gravity * delta


    # Handle Jump.
    if Input.is_action_just_pressed("Jump") and is_on_floor():
        velocity.y += jump_speed

    print(global_position)

    # Get the input direction.
    var direction = Input.get_axis("Left", "Right")
    velocity.x = direction * walk_speed

    move_and_slide()

I read in multiple forums that is_on_floor() only works when I have a downwards force pushing the object down. Would adding something like velocity.x += 0.1 to the horizontal movement work?

Energia | 2023-03-28 23:47

is_on_floor() works based on angle of tileset and detects whether the wall, slope or floor.
CharacterBody2D have builtin functionality of this.
It is working for me, So, I think it will work for you.
Thanks

DivinePart | 2023-03-28 23:54

Still gets stuck, is_on_floor() isn’t changing. Maybe it’s not a code problem; do you know any settings that may do this?

Energia | 2023-03-29 00:15

Try this and check the collision shapes and collision layers
Make sure that the character node and the Tileset can detect each others

extends CharacterBody2D
var speed = 1200
var jump_speed = -1800
var gravity = 4000
var friction = 0.1
var acceleration = 0.25


func _physics_process(delta):
    velocity.y += gravity * delta
    var dir = Input.get_axis("walk_left", "walk_right")
    if dir != 0:
        velocity.x = lerp(velocity.x, dir * speed, acceleration)
    else:
        velocity.x = lerp(velocity.x, 0.0, friction)

    move_and_slide()
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_speed

Zylo_X | 2023-03-29 07:03