Godot 4.2.2
So I’m trying to make a FNAF game and I’m trying to make an attack animation but it doesn’t work, and also it doesn’t give me any error?
My code:
if Input.is_action_pressed("Attack"):
$SpringTrapattack.visible == true
$AnimationPlayer.play("Attack")
await $AnimationPlayer.animation_finished
$SpringTrapattack.visible = false
Try
if $AnimationPlayer.is_playing:
await $AnimationPlayer.animation_finished
Is this supposed to be one equal sign? Is this being visible an important part of the animation?
This was brought up in the last thread created
and by the way, you should replace the double-equals to a single equal sign in the second line : if you don’t, you’re just evaluating a boolean expression (checking if the spring’s trap attack is visible) rather than assigning a new value to the variable (setting it to true here)
— ado
1 Like
Sorry but that did not work?
The problem is that the First Frame of the animation shows up but it does not play the rest, if you have any more questions please let me know!
add an if statement that checks if the animation is already playing.
And how exactly do you do that @thatultraguy because I’m new to the Godot community so .
im pretty sure it’s like this:
if $AnimationPlayer.is_playing() == false: #returns true if any animation is being played by the animation player
It does not work and doesn’t do anything at all?
If you wish to view the script here it is
extends CharacterBody2D
const SPEED = 200
const FAST_SPEED = 400
var current_speed = SPEED
const NORMAL_ANIMATION_SPEED = 1.0
const FAST_ANIMATION_SPEED = 2.0
var animation_speed = NORMAL_ANIMATION_SPEED
func _ready():
pass
func _physics_process(delta):
var motion = Vector2.ZERO
if Input.is_action_pressed("d"):
$Run.flip_h = false
motion.x += 1
$Attack.visible = false
$Hide.visible = false
$Run.visible = true
$Idle.visible = false
$AnimationPlayer.play("Run")
elif Input.is_action_pressed("a"):
$Run.flip_h = true
motion.x -= 1
$Run.visible = true
$Idle.visible = false
$AnimationPlayer.play("Run")
elif Input.is_action_pressed("s"):
motion.y += 1
$Run.visible = true
$Idle.visible = false
$AnimationPlayer.play("Run")
elif Input.is_action_pressed("w"):
motion.y -= 1
$Run.visible = true
$Idle.visible = false
$AnimationPlayer.play("Run")
else:
if $Run.flip_h == true:
$Idle.flip_h = true
else:
$Idle.flip_h = false
$AnimationPlayer.play("Idle")
$Run.visible = false
$Idle.visible = true
if Input.is_action_just_pressed("Hide"):
pass
if Input.is_action_just_pressed("Attack"):
$Attack.visible == true
$AnimationPlayer.play("Attack")
await $AnimationPlayer.animation_finished
$Attack.visible = false
if $AnimationPlayer.is_playing() == false:
print("Animation is not Playing")
motion = motion.normalized()
if Input.is_key_pressed(KEY_SHIFT):
current_speed = FAST_SPEED
animation_speed = FAST_ANIMATION_SPEED
else:
current_speed = SPEED
animation_speed = NORMAL_ANIMATION_SPEED
position += motion * current_speed * delta
And also now instead of Showing the First frame it does NOTHING at all
New updated Code:
extends CharacterBody2D
const SPEED = 200
const FAST_SPEED = 400
var current_speed = SPEED
const NORMAL_ANIMATION_SPEED = 1.0
const FAST_ANIMATION_SPEED = 2.0
var animation_speed = NORMAL_ANIMATION_SPEED
func _ready():
$AnimationPlayer.connect("animation_finished", Callable(self, "_on_animation_finished"))
func _process(delta):
if Input.is_action_just_pressed("Attack"):
$Attack.visible = true
$AnimationPlayer.play("Attack")
func _on_animation_finished(anim_name):
if anim_name == "Attack":
$Attack.visible = false
func _physics_process(delta):
var motion = Vector2.ZERO
if Input.is_action_pressed("d"):
$Run.flip_h = false
motion.x += 1
$Attack.visible = false
$Hide.visible = false
$Run.visible = true
$Idle.visible = false
$AnimationPlayer.play("Run")
elif Input.is_action_pressed("a"):
$Run.flip_h = true
motion.x -= 1
$Run.visible = true
$Idle.visible = false
$AnimationPlayer.play("Run")
elif Input.is_action_pressed("s"):
motion.y += 1
$Run.visible = true
$Idle.visible = false
$AnimationPlayer.play("Run")
elif Input.is_action_pressed("w"):
motion.y -= 1
$Run.visible = true
$Idle.visible = false
$AnimationPlayer.play("Run")
else:
if $Run.flip_h == true:
$Idle.flip_h = true
else:
$Idle.flip_h = false
$AnimationPlayer.play("Idle")
$Run.visible = false
$Idle.visible = true
if Input.is_action_just_pressed("Hide"):
pass
motion = motion.normalized()
if Input.is_key_pressed(KEY_SHIFT):
current_speed = FAST_SPEED
animation_speed = FAST_ANIMATION_SPEED
else:
current_speed = SPEED
animation_speed = NORMAL_ANIMATION_SPEED
position += motion * current_speed * delta
Ok your problem is that you areplaying a new animation every frame, it’s either “Run” or “Idle”. You need a condition around the Run/Idle animation to avoid playing during the attack animation.
I altered your script to use this if statement before playing “Run” or “Idle”
if $AnimationPlayer.current_animation != "Attack":
$AnimationPlayer.play("Run")
Here’s a simplified version of your script with the changes. also using CharacterBody2D’s physics with move_and_slide
extends CharacterBody2D
const SPEED = 200
const FAST_SPEED = 400
var current_speed = SPEED
const NORMAL_ANIMATION_SPEED = 1.0
const FAST_ANIMATION_SPEED = 2.0
var animation_speed = NORMAL_ANIMATION_SPEED
func _ready():
$AnimationPlayer.connect("animation_finished", Callable(self, "_on_animation_finished"))
func _on_animation_finished(anim_name):
if anim_name == "Attack":
$Attack.visible = false
func _physics_process(delta):
var motion := Input.get_vector("a", "d", "w", "s")
if not motion.is_zero_approx(): # running
if $AnimationPlayer.current_animation != "Attack":
$AnimationPlayer.play("Run")
$Run.flip_h = motion.x < 0
$Attack.visible = false
$Hide.visible = false
$Run.visible = true
$Idle.visible = false
else: # not running
if $AnimationPlayer.current_animation != "Attack":
$AnimationPlayer.play("Idle")
$Run.visible = false
$Idle.visible = true
$Idle.flip_h = $Run.flip_h
if Input.is_action_just_pressed("Hide"):
pass
if Input.is_action_just_pressed("Attack"):
$Attack.visible = true
$AnimationPlayer.play("Attack")
if Input.is_key_pressed(KEY_SHIFT):
current_speed = FAST_SPEED
animation_speed = FAST_ANIMATION_SPEED
else:
current_speed = SPEED
animation_speed = NORMAL_ANIMATION_SPEED
velocity = motion * current_speed
move_and_slide()
Ok thank you @gertkeno but there’s still a minor problem the other animations do stop but it displays something like this:
Maybe you could could fix that?
It’s part of the Attack animation part when it says:
if Input.is_action_just_pressed("Attack"):
$Run.visible = false
$Idle.visible = false
$Attack.visible = true
$AnimationPlayer.play("Attack")
I added it so that the Run and Idle aren’t being showed but it still shows them?
Not sure what you mean. I totally forgot about the sprite visibility flips on my example