Checking For Overlap, Without Physics Thread (Nor Signals)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Zakkle

Alright, so I have an designated number of objects, and I have to spawn all of them within a small space, without any of them overlapping. What’s more, I need this to be done at the time of the root scene’s _read(): function, without giving the physics thread time to detect an overlap in objects being placed.

I have it all setup to spawn the objects, randomize a valid coordinate, and place them there. What I don’t have, is the ability to get them to properly detect if they are overlapping without using the physics thread or signals.

if crate_arr[i].get_node("n_Crate/area_SpawnQuery").get_overlapping_areas().size() > 0:

This always returns 0, until the physics thread has had a second to process everything. I’ve also tried the overlapping_bodies() variation.

I have a collision detection that works; however, like I mentioned, this only works if I give the physics engine a second to process everything:

func _on_area_SpawnQuery_area_entered(area):
    SPAWN_COLLIDER = true

Once again, I’ve tried the other signal variations, such as body, etc. Doesn’t change the fact that I can’t get the results in time.

My most recent method:

var collider_size = $Crate/n_Crate/area_SpawnQuery/coll_SpawnQuery.shape.extents #crate_arr[num].get_node("n_crate/area_SpawnQuery/coll_SpawnQuery").shape.extents
var ray_topleft = Vector2(rand_x - collider_size.x, rand_y - collider_size.y)
var ray_bottomright = Vector2(rand_x + collider_size.x, rand_y + collider_size.y)

var space_state = get_world_2d().direct_space_state
var result = space_state.intersect_ray(ray_topleft, ray_bottomright, [self], 2)

… fails, because I don’t have whatever a world setup to use get_world_2d().direct_space_state, and I don’t like this raycasting method, because it’s just for setting up a bunch of lines, and not really looking for rectangles overlapping.

I have set up loops that will keep telling the crates to reposition if they are overlapping another, but it’s on a timer and it’s immersion-breaking, not to mention the loop is really useless unless you keep timing it to wait for the physics engine to re-process the moved crate.

I’ve been banging my head against the wall, trying to figure this out, for the past 24+ hours, and I’m not really getting anywhere.

How can I just use a simple rectangle to detect overlap with the designated masks, without having to manually recreate each child node’s collision area in a Rect2 for hundreds of instanced objects, of varying types, and causing an N^2 operation?

:bust_in_silhouette: Reply From: eons

The optimal and most simple way is to use the tools for overlap check (cast shapes in the direct space state) but you do not want that, I guess (I do not understand why).

Some options I can think of:

Get all your nodes, and use Shape2D api to check overlaps one by one with the currently instanced ones in the desired point.

Another is to put a set of fixed points where things will never overlap and use that set with zero checks (because was designed to not overlap).