Scale.x is causing the player to rapidly flick back and forth

Godot Version

4.4.1

Question

I am making a platformer game. I made an enemy that has two states, roaming back and forth and chasing. To flip the enemy, I used scale.x and set it to either -1 or 1 depending on the velocity of the enemy. When the scale.x goes to -1, the player rapidly flicks back and forth between scale.x = 1 and scale.x = -1. Why does this happen?

Here’s my code for the enemy:

extends CharacterBody2D

@export var char : CharacterBody2D

var speed = 100.0
var distance_from_player

func _physics_process(delta: float) → void:
distance_from_player = position.x - char.position.x
velocity.x = speed
scale.x = scale.x * sign(speed)
if not is_on_floor():
velocity += get_gravity() * delta
elif !is_on_floor() and velocity.y >= 0:
velocity.y += 5

move_and_slide()

Here’s his roaming state:

extends State

@export var enemy : CharacterBody2D
@export var spot_players : RayCast2D
@export var spot_walls : RayCast2D
@export var spot_floors : RayCast2D

func enter(previous_state_path: String, data := {}) → void:
enemy.speed = enemy.speed * -1

func physics_update(_delta: float) → void:
if spot_walls.is_colliding():
enemy.speed = enemy.speed * -1
if !spot_floors.is_colliding():
enemy.speed = enemy.speed * -1
if spot_players.is_colliding():
finished.emit(“Spotted”)
enemy.move_and_slide()

And here’s his chasing state:

extends State

@export var enemy : CharacterBody2D
@export var spot_players : RayCast2D
@export var spot_walls : RayCast2D
@export var spot_floors : RayCast2D
@export var spotted_timer : Timer

func physics_update(_delta: float) → void:
if sign(enemy.distance_from_player) == 1:
enemy.speed = 100
else:
enemy.speed = -100
if !spot_players.is_colliding():
finished.emit(“Roam”)

If the sign of speed is negative, then multiplying the scale by it every frame will result in it flipping between positive and negative every frame (-1 * -1 = 1). Also, you shouldn’t change the scale of physics objects, the engine isn’t designed to handle that well. You should flip the sprite instead.

1 Like