Problems with hit boxes and attack animation

godot version 4.6 After watching tutorial on a Godot 4 3D - FPS Melee Attack and currently having a problem. I made animations for attacking and idle, as well as added the “enemy” as a group. I have added code to make animation to play when press the left mouse key as tutorial has stated as well added when the attack animation is finished to start and loop animation idle to play but it doesn’t seem to switch to idle animation.

If anyone can help that would be much appreciated.

-https://youtu.be/OFRtk8I5UxY

extends RigidBody3D

var mouse_sensitivity := 0.001
var twist_input := 0.0
var pitch_input := 0.0

@onready var twist_pivot := $TwistPivot
@onready var pitch_pivot := $TwistPivot/PitchPivot
@onready var anim_player = $AnimationPlayer
@onready var hitbox = $CollisionShape3D/MeshInstance3D/WeaponPivot/WeaponMesh/Hitbox

func _ready() → void:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _process(delta):
var input := Vector3.ZERO
input.x = Input.get_axis(“move_left”, “move_right”)
input.z = Input.get_axis(“move_forward”, “move_back”)

if Input.is_action_just_pressed("quit"):
	get_tree().quit()

if Input.is_action_just_pressed("attack"):
	anim_player.play("attack")
	hitbox.monitoring = true

apply_central_force(twist_pivot.basis * input * 1200.0 * delta)

var aligned_force = twist_pivot.basis * input

if Input.is_action_just_pressed("ui_cancel"):
	Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
twist_pivot.rotate_y(twist_input)
pitch_pivot.rotate_x(pitch_input)
pitch_pivot.rotation.x = clamp(pitch_pivot.rotation.x, 
	deg_to_rad(-30), 
	deg_to_rad(30))

twist_input = 0.0
pitch_input = 0.0

func _unhandled_input(event: InputEvent) → void:
if event is InputEventMouseMotion:
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
twist_input = - event.relative.x * mouse_sensitivity
pitch_input = - event.relative.y * mouse_sensitivity

func _on_animation_player_animation_finished(anim_name):
if anim_name == “attack”:
anim_player.play(“idle”)
hitbox.monitoring = false

func _on_hitbox_area_entered(area):
if area.is_in_group(“enemy”):
print(“enemy hit”)

Please post the relevant code, we can’t help you without seeing your code.

Apologies added

The code you added relies on AnimationPlayer.animation_finished to return to idle. In Godot, that signal is only emitted when a non-looping animation reaches its end. Check the Animation panel for attack and turn Loop off, and verify the exact animation name is attack and the signal is connected to this same AnimationPlayer.

A simple structure would be:

gdscript
func _input(event: InputEvent) -> void:
    if event.is_action_pressed("attack"):
        hitbox.monitoring = true
        anim_player.play("attack")

func _on_animation_player_animation_finished(anim_name: StringName) -> void:
    if anim_name == &"attack":
        hitbox.set_deferred("monitoring", false)
        anim_player.play("idle")
```

If you do not want attacks to restart while one is playing, add `and not anim_player.is_playing()` to the input condition. Also check that the attack animation itself does not contain a method track that calls `play("attack")` again, since that would keep it from reaching its end.

As requested i have changed the code to the above and have made sure the attack animation is not looping and the exact animation name is attack the signal is also connected to the same animation player. its sadly still not working

extends RigidBody3D

var mouse_sensitivity := 0.001
var twist_input := 0.0
var pitch_input := 0.0

@onready var twist_pivot := $TwistPivot
@onready var pitch_pivot := $TwistPivot/PitchPivot
@onready var anim_player = $AnimationPlayer
@onready var hitbox = $CollisionShape3D/MeshInstance3D/WeaponPivot/WeaponMesh/Hitbox

func _ready() → void:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _process(delta):
var input := Vector3.ZERO
input.x = Input.get_axis(“move_left”, “move_right”)
input.z = Input.get_axis(“move_forward”, “move_back”)

if Input.is_action_just_pressed("quit"):
	get_tree().quit()

if Input.is_action_just_pressed("attack"):
	anim_player.play("Attack")
	hitbox.monitoring = true

apply_central_force(twist_pivot.basis * input * 1200.0 * delta)

var aligned_force = twist_pivot.basis * input

if Input.is_action_just_pressed("ui_cancel"):
	Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
twist_pivot.rotate_y(twist_input)
pitch_pivot.rotate_x(pitch_input)
pitch_pivot.rotation.x = clamp(pitch_pivot.rotation.x, 
	deg_to_rad(-30), 
	deg_to_rad(30))

twist_input = 0.0
pitch_input = 0.0

func _unhandled_input(event: InputEvent) → void:
if event is InputEventMouseMotion:
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
twist_input = - event.relative.x * mouse_sensitivity
pitch_input = - event.relative.y * mouse_sensitivity

func _input(event: InputEvent) → void:
if event.is_action_pressed(“attack”):
hitbox.monitoring = true
anim_player.play(“Attack”)

func _on_animation_player_animation_finished(anim_name: StringName) → void:
if anim_name == &“attack”:
hitbox.set_deferred(“monitoring”, false)
anim_player.play(“idle”)

func _on_hitbox_area_entered(area):
if area.is_in_group(“enemy”):
print(“enemy hit”)