How do I get is_on_floor() to work properly?

Attention Topic was automatically imported from the old Question2Answer platform.

Hi all,

I’m trying to make the player rotate when they jump, then rotate back to normal when they land. I’ve finished the basic movement mechanics so far, however when the player is moving along an edge of a platform, the player rotates back and forth very fast, as if is_on_floor() is returning both True and False. This is my code:

``````extends KinematicBody2D

var velocity = Vector2.ZERO

const SPEED = 250
const GRAVITY = 30
const JUMPFORCE = -850

func _physics_process(_delta):
# Check for input. If there's no input, change the animation to idle
var is_idle = true
if Input.is_action_pressed("move_left"):
is_idle = false
velocity.x = -SPEED
if Input.is_action_pressed("move_right"):
is_idle = false
velocity.x = SPEED

if is_idle:
\$AnimatedSprite.animation = "idle"
if is_on_floor():
velocity.y = 1
else:
\$AnimatedSprite.animation = "walk"

if Input.is_action_pressed("move_jump") and is_on_floor():
velocity.y = JUMPFORCE

if is_on_floor() or is_on_wall():
\$AnimatedSprite.rotation = TAU
else:
\$AnimatedSprite.animation = "idle"
\$AnimatedSprite.rotation_degrees += 15
velocity.y += GRAVITY

velocity = move_and_slide(velocity, Vector2.UP)
velocity.x = lerp(velocity.x, 0, 0.02)

if velocity.length() > 0:
\$AnimatedSprite.play()
else:
\$AnimatedSprite.stop()

if velocity.x != 0:
\$AnimatedSprite.animation = "walk"
\$AnimatedSprite.flip_v = false
\$AnimatedSprite.flip_h = velocity.x < 0
``````

Could someone tell me how to stop the character rotating back and forth?

Apply “gravity” at a constant rate. The `velocity.y = 1` during idle is probably causing an inconsistent/jittery return of`is_on_floor()` since velocity.y will bounce between 0-1 every frame. Constant gravity will keep the KinematicBody in “collision” with the floor and ensure that `is_on_floor()` calls are consistent.

Here’s my edited code that seemed to fix the issue:

``````extends KinematicBody2D

var velocity = Vector2.ZERO
var grounded
var on_wall

const SPEED = 250
const FRICTION = 10
const GRAVITY = 30
const JUMPFORCE = -850

func _physics_process(delta):
# Check for input. If there's no input, change the animation to idle
var is_idle = true
if Input.is_action_pressed("move_left"):
is_idle = false
velocity.x = -SPEED
if Input.is_action_pressed("move_right"):
is_idle = false
velocity.x = SPEED

if is_idle:
\$AnimatedSprite.animation = "idle"
else:
\$AnimatedSprite.animation = "walk"

if Input.is_action_just_pressed("move_jump") and is_on_floor():
velocity.y = JUMPFORCE

if is_on_floor() or is_on_wall():
\$AnimatedSprite.rotation = TAU
else:
\$AnimatedSprite.animation = "idle"
\$AnimatedSprite.rotation_degrees += 15

velocity.y += GRAVITY
if is_idle:
velocity.x = lerp(velocity.x, 0, FRICTION * delta)
velocity = move_and_slide(velocity, Vector2.UP, false)

if velocity.length() > 0:
\$AnimatedSprite.play()
else:
\$AnimatedSprite.stop()

if velocity.x != 0:
\$AnimatedSprite.animation = "walk"
\$AnimatedSprite.flip_v = false
\$AnimatedSprite.flip_h = velocity.x < 0
``````

This worked well. Thanks!

jtbx | 2022-11-07 20:47