Hi! I’m trying to create the logic for the main mechanic of my game. Basically what it needs to happen is that if an enemy Area2D enters the Area2D of the player (I’m using this node for now but let me know if there are better nodes to do this), the enemy progress bar starts to fill up. Do you have any suggestions on how to do so? Also this system needs to be modular(idk if it’s the right term for this) meaning that there are different enemies and they’re going to have bigger/smaller max values for the progress bars, and the player can increase the rate at which they fill up through upgrades.
In the script assigned to the Area2D you can use the “get_overlapping_bodies” function to get all the object inside the area. Then loop through all the bodies and check if they have the charge function on them and if they do, call it.
Alternatively you could register and deregister the objects with the body_entered and body_exited. That’s probably what I would do.
Untested Pseudo Code
extends Area2D
var objects_in_area = []
var charge_per_second = 5.0
func _ready():
body_entered.connect(on_body_entered)
body_exited.connect(on_body_exited)
func _process(delta) -> void:
for obj in objects_in_area:
obj.charge_power(charge_per_second * delta)
func on_body_entered(body):
# only objects that have the right function get added to the list by using has_method to qualify them
if body.has_method("charge_power"):
objects_in_area.append(body)
func on_body_exited(body):
objects_in_area.erase(body)
Doing this per frame could be costly if its a lot of objects. Its the easiest solution from a code point of view, but not from a performance point of view.
Its far better do it from the enemy point of view, if the enemy enters the player area it does the work instead. That way only the enemies in the area are running that code.
The player shoudlnt need to worry about what the enemies are doing in good OOD design.
So I’m liking @Arnklit’s logic and I want to test it out. I was writing some code on my own and I’m kind of stuck. Basically I want that the single enemy does the calculation like @OriginalBadBoy said but I can’t figure out how to make the collision shape of the enemy communicate with the Area2D of the player. Should I had an Area2D to the enemy also?
So I would not worry about performance early on, just try stuff out and play around. So if you would rather do it from the enemies point of view. You can do something like this.
extends Area2D
@onready var halo_area = get_tree().get_first_node_in_group("halo")
func _process(delta) -> void:
if overlaps_area(halo_area):
# Perform logic for charging
Note you’d have to set the halo areas group as “halo” as that is how I get the reference in this example.
I’d rather use get_overlapping_areas + timer.
To summarize: you get a list of overlapping areas, then iterate through it, checking objects for a group, name or tag. If you catch what you need, call the method from the side of the caught one.
As for performance, it is not necessary to call the method every frame… it is enough to connect a timer with a period of, for example, 0.2 seconds.
Implementation option in C#:
Where I have GD.Print(area), you will call the method of the same name from the side of the mobs, where a parameter will be specified in the mob itself that affects the speed of filling the progress bar.