When is it safe to call get_overlapping_bodies()

Godot Version

4.2.1

Question

I am making a spell that hits enemies in it’s area. I would like to make one version that does this once and one that does this damage over time at a certain interval. The one that does it once is easy enough. However, I’m not sure what the best solution is for the one that does it multiple times. I’ve gotten 3 different methods working, but each seems a bit hacky and I’m not sure if there is a better way. Unfortunately I don’t have version management going at the moment since I’ve just been playing around, so I don’t have the exact code, but I just want to get an idea of how these different functions work.

Option 1: I called the damage function in physics process and had some if statement to only allow it in after certain intervals.

Option 2: I use the on_body_entered signal to call a damage function that enters a while loop and used a timer to only allow it through an if statement when the timer was zero.

Option 3: The latest attempt was to use a timer signal to trigger the damage function whenever the timer ran out for the interval I wanted. The problem with this is that it obviously doesn’t do anything right when the spell happens, which is what I want. I tried just calling the damage function once in _ready(), but that results in get_overlapping_bodies() not returning any bodies. The hacky solution was just to initially start the interval timer at a short time (.02), and then set it to the right time when the timeout function is called. This seems a bit wrong. I’m basically using a magic number to delay it then I’m calling the timer.start() function each time rather than just letting it loop by default.

Could anyone give me a good explanation of what the best way of approaching? Also, I could use an explanation of the timing of the ready function and how/where I should call code that needs to make sure everything is in place first. (I thought that was what ready was for, but I guess not?)

1 Like

Option 2 with a signal, but use an animation player to call the damage function.

Option 2 seems a little risky to me, you would need to be very careful using a while loop whilst using signals as you could end up in an infinite loop,.

get_overlapping_bodies() is updated in the physics step, so it is intended to be used in _physics_process(). My personal opinion is that the _ready() function (or maybe _init() should make a call to the physics step so things like this work in _ready(), but they don’t.

Physics are not available on an object’s first frame (when _ready() is called). You will have to wait until the second frame before get_overlapping_bodies() will work. You can accomplish this by using it in _physics_process().

_ready() is indeed usually where you put your object’s initialization code. It gets called when your object enters the scene tree. You can also use _init(), which is called before _ready(), for some things, but nothing in your scene is available at this point. ready() is what you want the vast majority of the time.

In the five years I’ve been using godot, I have never tried doing any physics work in _ready(). I frequently use physics calls in _process(), though, as I’ve had major slowdowns with _physics_process() in some projects.

1 Like