Godot Version
4.3
Question
Hi! I’m trying to implement an attack animation into my game, and it doesn’t work. I know it has something to do with the physics process and how it works every second, and there is a lot of fixes for that. Still, I don’t understand how to implement them as I do movement animations with an Animated Sprite, and this particular attack with Animation Player, as I need collision shapes to be in the animation.
Is mixing those two a problem here?
When I press the attack button the animations technically plays - “ATTACK” is printed and the collision shape lights up for when the attack is supposed to hit, but the animation of the sprite itself shows up for just a split-second.
What should I do here?
I’d really appreciate your help.
extends CharacterBody2D
const SPEED = 130.0
var JUMP_VELOCITY = -360.0
const gravity = 1000
const fall_gravity = 1200
var is_wall_slide = false
var wall_jump_power = 300
const wall_slide_gravity = 50
var is_attacking = false
var is_flipped = false
@onready var animation_player = $AnimatedSprite2D/AnimationPlayer
@onready var animated_sprite = $AnimatedSprite2D
@onready var all_interactions = []
@onready var interactLabel = $"interaction/InteractLabel"
# Jump Curve
func apply_gravity(velocity :Vector2):
if velocity.y < 0:
return gravity
else:
return fall_gravity
func _physics_process(delta):
# Interaction
if Input.is_action_just_pressed("interact"):
execute_interaction()
if Input.is_action_just_pressed("attack"):
attack()
# Add the gravity.
if not is_on_floor():
velocity.y += apply_gravity(velocity) * delta
# Handle jump.
if Input.is_action_just_pressed("jump"):
if is_on_floor():
velocity.y = JUMP_VELOCITY
elif is_on_wall():
velocity.y = JUMP_VELOCITY
velocity.x = get_wall_normal().x * wall_jump_power
# Release Jump
if Input.is_action_just_released("jump") and velocity.y < 0:
velocity.y = JUMP_VELOCITY / 4
# Get the input direction: -1, 0, 1.
var direction = Input.get_axis("move_left", "move_right")
if direction:
velocity.x = move_toward(velocity.x, direction * SPEED, 36.0)
else:
velocity.x = move_toward(velocity.x, 0, 36)
move_and_slide()
wall_slide(delta)
attack()
# Flip the spirte
if direction > 0:
animated_sprite.flip_h = false
is_flipped = false
elif direction < 0:
animated_sprite.flip_h = true
is_flipped = true
# Play animation
if is_on_floor():
if Input.is_key_pressed(KEY_I):
animated_sprite.play("idle_suit")
else: if direction == 0:
animated_sprite.play("idle")
else:
animated_sprite.play("run")
else:
animated_sprite.play("jump")
if is_wall_slide:
animated_sprite.play("wall_land_right")
if is_attacking and !is_flipped:
animation_player.play("attack_stab_right")
elif is_attacking and is_flipped:
animation_player.play("attack_stab_left")
func wall_slide(delta):
# Wall Slide
if is_on_wall() and !is_on_floor():
if Input.is_action_pressed("move_left") or Input.is_action_pressed("move_right"):
is_wall_slide = true
else:
is_wall_slide = false
else:
is_wall_slide = false
if is_wall_slide:
velocity.y += (wall_slide_gravity * delta)
velocity.y = min(velocity.y, wall_slide_gravity)
func attack():
if is_on_floor() and Input.is_action_just_pressed("attack"):
is_attacking = true
print("ATTACK")
else:
is_attacking = false
#interactions
func _on_area_2d_area_entered(area):
all_interactions.insert(0, area)
update_interactions()
func _on_area_2d_area_exited(area):
all_interactions.erase(area)
update_interactions()
func update_interactions():
if all_interactions:
interactLabel.text = all_interactions[0].interact_label
else:
interactLabel.text = ""
func execute_interaction():
if all_interactions:
var cur_interaction = all_interactions[0]
match cur_interaction.interact_type:
"swap_weapon": $Weapon.set_texture(load("res://assets/items/weapons/crossbow.png"))