Hey!! Thanks for getting back to me : - ) (Apologies for a REALLY long reply, I wanted to be very thorough in my documentation.)
I used this code as you said:
func _on_enemy_box_area_entered(area) -> void:
await get_tree().process_frame
if area.attacking:
attacked = true
print("attacked")
func _on_enemy_box_area_exited(area) -> void:
pass
func _physics_process(delta):
if attacked:
hide()
…and it does not print “attacked”
The error is coming from the “area.attacking.”
Probably this is important and I should’ve mentioned it earlier, but the InteractBox is only a child of the Player node, and it has its own code (there is nothing in the InteractBox code except for a class name declaration.) The variable “attacking” is only inside of the Player script and not the InteractBox script.
I tried doing this
func _on_enemy_box_area_entered(area) -> void:
await get_tree().process_frame
if (Player is attacking && area is InteractBox):
attacked = true
print("attacked")
and received the error: “Could not find type “attacking” in the current scope.”
From my knowledge of Java, I tried making a method in player that would return the value of “attacking",” then calling that method in InteractBox, which would then give it a value accessable by the Enemy code. Here’s what I ended up doing:
# this is in the InteractBox, which is a child of my player
func isAttacking():
return get_parent().attacking
# this is in my enemy's code
func _on_enemy_box_area_entered(area) -> void:
await get_tree().process_frame
if area is InteractBox && area.isAttacking:
print("attacked")
Using this code, “attacked” IS printed when the attack area enters the enemy hitbox.
# this is the whole enemy code
extends CharacterBody2D
class_name Enemy
var attacked= false
func _on_enemy_box_area_entered(area) -> void:
await get_tree().process_frame
if area is InteractBox && area.isAttacking:
attacked = true
print("in")
func _on_enemy_box_area_exited(area) -> void:
if area is InteractBox:
attacked = false
print("out")
func _physics_process(delta):
if attacked && Input.is_action_just_pressed("attack"):
print("attacked")
hide()
pass
With the above code, “in” is printed frame perfect, “out” is printed frame perfect, and “attacked” is never printed. If I remove the “&& Input.is_action_just_pressed(“attack”)” then “attacked” is printed and the enemy sprite hides on the first frame of the attack.
My problem with this is that attacked is continuously printed for the entire duration of the attack, which means that the enemy would hide at ANY point during the attack instead of only on the first frame.
So THEN I tried to do this:
func _on_enemy_box_area_entered(area) -> void:
if area is InteractBox && area.isAttacking:
attacked = true
print("in")
func _on_enemy_box_area_exited(area) -> void:
if area is InteractBox:
attacked = false
print("out")
func _physics_process(delta):
if Input.is_action_just_pressed("attack"):
await get_tree().process_frame # this await is intended to have the function pause for one frame such that "attacked" needn't be true frame perfect.
if attacked:
print("attacked")
hide()
pass
This one prints out “in” and “out” but never “attacked”… it doesn’t make sense to me! When “attack” is pressed, that will be true, then it will wait one frame, and check if “attacked” is true, which it WILL be because “attacked” is now also frame perfect… I’m completely stumped.
It works, but it still isn’t frame perfect. I’m convinced it may be impossible to ensure that “attacked” is only printed on the earliest frame after “attack” is pressed that “attacked” is true…
I’m going to mark this as solved, because my original problem HAS been solved… but I’d still appreciate any further feedback in this thread or in my DMs.