Godot Version
4.3
Question
` I’m trying to have my character attack with a hurtbox in my platformer
game. The problem is in trying to have the hurtbox become active only when
I’m attacking and also having the hurtbox active only during a frame or two during the attack. So far no luck. I’ve tried adding a Call Back track in the animation player and then use the hitbox itself as the method, but I can’t make the thing work for some reaon. Does anyone have a simple and effective solution for this problem? I’ll share my scripts here:
Hitbox:
class_name HitBox
extends Area3D
@export var _damage: int = 1
func _ready():
set_hitbox_enabled(false)
func set_hitbox_enabled(value: bool):
monitoring = value # Enable or disable detection
for child in get_children():
if child is CollisionShape3D:
child.disabled = !value # Enable/disable collision shape # Hitbox disabled by default
func set_damage(value: int):
_damage = value
func get_damage() -> int:
return _damage
Character controller:
class_name PlayerEntity
extends CharacterBody3D
@export var SPEED = 3.0
@export var JUMP_VELOCITY = 4.5
@export var acceleration = 12.0
@export var deceleration = 10.0
@export var gravity_multiplier = 1.0 # Multiplier for gravity
@export var attacking = false
@onready var animation: = $AnimationPlayer
@onready var hitbox = $HitBox/CollisionShape3D
@onready var sprite_3d = $Sprite3D
# Connect the animation_finished signal to reset 'attacking' flag when attack animation finishes
func _process(_delta: float) -> void:
if Input.is_action_just_pressed("attack"):
attack()
func _physics_process(delta: float) -> void:
# Modify gravity multiplier based on player state
if not is_on_floor():
if velocity.y > 0: # Ascending (jumping up)
gravity_multiplier = 1.0 # Normal gravity
else: # Descending (falling down)
gravity_multiplier = 2.0 # Increased gravity
velocity += get_gravity() * gravity_multiplier * delta
else:
gravity_multiplier = 1.0 # Reset gravity when on the floor
# Handle jump release for short hop
if Input.is_action_just_released("jump") and velocity.y > 0:
velocity.y *= 0.5
# Handle jump
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
# Get input for horizontal movement
var input_dir = Input.get_vector("left","right", "ui_up", "ui_down")
#Constrain the movement to X and Y vectors
var move_dir = Vector3(input_dir.x, 0, input_dir.y)
if attacking and is_on_floor(): #stops the player from moving when is attacking
velocity = Vector3.ZERO
else:
velocity.x = move_toward(velocity.x, move_dir.x * SPEED, acceleration * delta)
if input_dir.x > 0:
$Sprite3D.scale.x = 1
elif input_dir.x < 0:
$Sprite3D.scale.x = -1
#Decelerate when no input is given
if move_dir == Vector3.ZERO:
velocity.x = move_toward(velocity.x, input_dir.x * SPEED, acceleration * delta)
# Move the character
move_and_slide()
# Handle animations
update_animation(Vector3(input_dir.x, 0, 0))
func attack():
attacking = true
animation.play("attack_1")
func update_animation(_direction: Vector3) -> void:
if !attacking:
if velocity.y > 0: # Ascending
animation.play("jump")
elif velocity.y < 0 and not is_on_floor(): # Descending
animation.play("Fall")
if velocity.x != 0 and is_on_floor():
animation.play("run") # Optional fall animation
elif velocity.x == 0 and is_on_floor():
animation.play("idle")
else: # Idle
animation.play("attack_1")
Any help is greatly appreciated! `
-Chris