I’m trying to add a crouch animation that consists of just two frames. I’m using AnimationPlayer, it all works except that the animation takes just the first frame and skip the second. All other animations like run and jump work fine, it’s just the crouch one.
I think the problem might be here maybe ?
if is_on_floor():
if is_crouching:
animation_player.play("crouch")
#Crouch
if Input.is_action_just_pressed("crouch"):
crouch()
elif Input.is_action_just_released("crouch"):
stand()
move_and_slide()
func crouch():
is_crouching = true
func stand():
is_crouching = false
There is an issue with the way you play the crouch animation. It looks like it calls play every time is_on_floor is true while the player is crouching, which makes the animation start over and over again because it is being called to play every process frame. Try adding a statement that checks if the crouch animation has already finished before the animation_player.play("crouch"). Hope this helps!
Try swapping if is_crouching for if is_crouching and not animation_player.is_playing(). Additionally, if you haven’t already, you can set the loop mode of the animation to “linear” so the animation keeps repeating and doesn’t need to be restarted all the time.
Oh my bad, I assume that’s because you’re already playing an animation before crouching? In that case, I would just move the animation_player.play("crouch") into crouch() (without keeping the if-statements) If there is no other animation playing and moving the line doesn’t work I don’t know what could work, sorry
It’s just a total basic 2d crouch animation, so it should start when idle or when running. It does work, but it’s a two-frame animation and it only use the first frame. I’m totally new to coding and my brain is melting as i come from 2d/3d art and it’s not this brutal
This is the script attached to the player, can anyone tell me if something might be blocking the crouch animation from displaying the second frame ? (it’s a two-frame animation):
extends CharacterBody2D
const SPEED = 150
const JUMP_VELOCITY = -300.0
@onready var animation_player: AnimationPlayer = $AnimationPlayer # Adjust path if necessary
var reverse_to_right = false
var reverse_to_left = true
var is_animation_finished = true
var moving_left := false # Defaults to false
var is_crouching = false
@onready var sprite = $Sprite2D
func _physics_process(delta: float) -> void:
# Add the gravity
if not is_on_floor():
velocity += get_gravity() * delta
# Handle jump
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
# Get the input direction and handle the movement/deceleration.
var direction := Input.get_axis("move_left", "move_right")
# Flip the sprite
if direction > 0:
$Sprite2D.flip_h = false # Assuming your Sprite node is named "Sprite2D"
elif direction < 0:
$Sprite2D.flip_h = true # Flip horizontally if moving left
#else:
$Sprite2D.flip_h = $Sprite2D.flip_h # No change if direction is 0 (optional, you could remove this line)
# Play animations
if is_on_floor():
if direction == 0:
animation_player.play("idle")
else:
animation_player.play("run")
else:
animation_player.play("jump")
#Crouch Animation
if is_on_floor():
if is_crouching:
animation_player.play("crouch")
#Collision for crouching
if Input.is_action_pressed("crouch"):
$CollisionShapeCrouch.disabled = false
$CollisionShapeStanding.disabled = true
else:
$CollisionShapeCrouch.disabled = true
$CollisionShapeStanding.disabled = false
# Apply Movement
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
#Crouch
if Input.is_action_just_pressed("crouch"):
crouch()
elif Input.is_action_just_released("crouch"):
stand()
move_and_slide()
func crouch():
is_crouching = true
func stand():
is_crouching = false
Try adding this helper function that checks if the current animation is different from the one being requested:
func play_animation(requested: String) -> void:
if animation_player.current_animation != requested:
animation_player.play(requested)
Then change your animation state handling from this:
# Play animations
if is_on_floor():
if direction == 0:
animation_player.play("idle")
else:
animation_player.play("run")
else:
animation_player.play("jump")
#Crouch Animation
if is_on_floor():
if is_crouching:
animation_player.play("crouch")
to this:
if is_on_floor():
if Input.is_action_pressed("crouch"):
play_animation("crouch")
elif direction == 0:
play_animation("idle")
else:
play_animation("run")
else:
play_animation("jump")
Also, I suggest you optimize your code because there are a lot of redundancies and unnecessary functions.