Godot 4
Pretty much what the title says.
This is my node structure ^
(I’m using AnimatedSprite2D, not
This is my hitbox code:
class_name Hitbox
extends Area2D
@export var damage = 1
func _init() → void:
collision_layer = 2
collision_mask = 0
I want a way to disabled and enable the hitboxes (in other scripts maybe) depending on whether a certain animation is playing or not, but I can’t figure out how to do it with code. Is it possible, or would I have to do it another way?
You could change the collision mask value within an Animation. Otherwise through code you can run the same snipped you posted before and after an animation plays.
1 Like
Alright, thanks. I’ll try this out and hopefully it’ll work.
You can also hide desired nodes, it will stop them from processing and being counted in collision. Might be more straight forward if you want to disable collision completely, rather than editing collision mask by itself.
1 Like
This is my code for player1.
extends CharacterBody2D
@export var movement_speed : float = 50
@export var health : int = 12
var character_direction : Vector2
var is_attacking = false
var can_flip = true
var bounce_count = 0
var current_state : String = "idle"
var previous_state : String = "idle"
@onready var hitbox = $p1sprite/Hitbox
@onready var p1sprite = $p1sprite
@warning_ignore("unused_parameter")
func _physics_process(delta): ## movement code
if current_state == "hurt":
return
character_direction.x = Input.get_axis("p1left", "p1right")
character_direction.y = Input.get_axis("p1up", "p1down")
character_direction = character_direction.normalized()
if can_flip == true: ## code to flip sprite (disabled if ur attacking)
print(has_node("Hitbox"))
print(get_node("Hitbox"))
if character_direction.x > 0:
p1sprite.flip_h = false
elif character_direction.x < 0:
p1sprite.flip_h = true
if is_attacking == false:
if character_direction:
velocity = character_direction * movement_speed
p1sprite.play("move")
current_state = "move"
else:
velocity = velocity.move_toward(Vector2.ZERO, movement_speed)
p1sprite.play("idle")
current_state = "idle"
else:
velocity = character_direction * movement_speed
move_and_slide()
attack()
func attack(): ## like rock paper scisors. bounce is the hand motion thing u do, and shoot is when u shoot (duh).
if Input.is_action_just_pressed("p1rock") and !is_attacking:
is_attacking = true
can_flip = false
p1sprite.play("bounce")
print("current animation: ", p1sprite.animation)
func _on_p_1_sprite_animation_looped(): ## keeps track of how many bounces u've done. needs 3 before shooting because ROCK (1) PAPER (2) SCISSORS (3).
if p1sprite.animation == "bounce":
bounce_count += 1
print(bounce_count)
if bounce_count == 3:
bounce_count = 0
print("bounce count reset")
p1sprite.play("shoot")
func _on_p_1_sprite_animation_finished(): ## handles what happens after u shoot (so like the actual attack, bounces are just the warm up).
if p1sprite.animation == "hurt":
current_state = "idle"
is_attacking = false
can_flip = true
p1sprite.play("idle")
elif p1sprite.animation == "shoot":
is_attacking = false
can_flip = true
print("shoot done")
if has_node("Hitbox"):
hitbox.collision_layer = 2
print("hitbox active")
func take_damage(damage: int) -> void: ## for when u get hit (death code not done yet)
health -= damage
print("Health: ", health)
if health <= 0:
print ("u died")
return
if current_state != "hurt":
current_state = "hurt"
if is_attacking:
is_attacking = false
bounce_count = 0
print("bounce count interrupted - now reset")
if p1sprite:
p1sprite.play("hurt")
I want the player’s hitbox to only be only layer 2 (same layer as the collision_mask, so active) during the shoot animation, (it is layer 3 (id 4) by default) and deactivated after the shoot animation (so back to layer 3). For some reason, I can’t reference the Hitbox node, so I can’t hide or change the layer of the nodes.
When running, the debugger shows this:
p1script.gd:25 @ _physics_process(): Node not found: “Hitbox” (relative to “root/game/player1”).
When using print(), it also just says that it can’t find the object and null.
While you can set collision layers from code as well, It seems to me AnimationPlayer
would also be great here. You can create an animation that just puts collision to layer 2, and call it via code like anim_player.play("disable_collision")
assuming you named it disabled_collision
1 Like
Alright, I’ll try this out.