How to get the nearest object in a group?

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

Hello there!

I am still learning about programming, so please, talk with me like you would talk to a kid :slight_smile:

For my project in v3.0, I want to respawn my dead player on an instanced spawnpoint (there can be many in my game) that is closest to my player once he is dead. I wrote a code that you can see below.

The question is:
How to make it work? I mean, the position I am trying to get via the code is still nil. I am not able to figure out what to change. I think that the var A should be something else, but I don’t know what to put as a value.

Or how would you rewrite the function to work?

Thank you in advance! :slight_smile:

The code is:

func respawn_player():
var nearest_spawnpoint = null
var min_distance = 100000
var space_stations = get_tree().get_nodes_in_group("space_station")
var A = space_stations[0]

for B in space_stations:
	if B == A:
		continue
	var distance_to_spawnpoint = global_position.distance_to(B.global_position)
	if distance_to_spawnpoint < min_distance:
		min_distance = distance_to_spawnpoint
		nearest_spawnpoint = B
	
var new_pos_x = nearest_spawnpoint.global_position.x
var new_pos_y = nearest_spawnpoint.global_position.y
global_position = Vector2(new_pos_x, new_pos_y)
current_health = max_health
can_move = true
:bust_in_silhouette: Reply From: Diet Estus

I might do something like this:

func respawn_player():
    # get spawn nodes
    var spawn_points = get_tree().get_nodes_in_group("space_stations")

    # assume the first spawn node is closest
    var nearest_spawn_point = spawn_points[0]

    # look through spawn nodes to see if any are closer
    for spawn_point in spawn_points:
         if spawn_point.global_position.distance_to(player.global_position) < nearest_spawn_point.global_position.distance_to(player.global_position):
            nearest_spawn_point = spawn_point

    # reposition player
    player.global_position = nearest_spawn_point.global_position

If you’re running this script from your player node, simply remove references to player.

This looks a way better than my code. But I am getting an error: “Invalid get index ‘0’ (on base: Array)”. Does it mean that the group is empty or what?

IranosMorloy | 2018-04-28 19:09

Yes, I believe so. I see you used “space station” as the group name in your original post, but I used “space stations”, plural. That might be the issue.

Diet Estus | 2018-04-28 19:12

Nope. Your code works fine! I just had a mistake in one word. Cool, works fine! Thank you! Really appreciate that:-)

IranosMorloy | 2018-04-28 19:12

Hm, that is an O(N) solution. I was hoping that Godot internally maintains a KDTree which we can exploit for O(log N) lookup. In my use case the number of things to look up is large, and the linear lookup is prohibitively slow…

bluenote | 2019-12-19 16:50

hey !
How would you proceed to get the 2nd nearest spawn point ?

quizzcode | 2020-05-22 01:53

Have you found any solution to this?
I too am looking for some way to optimize it.

Microices | 2022-04-14 12:15

Arrays have a min() function. Going through an array that holds similar types of data e.g Vectors, floats or integers, you can get the smallest one in an array using min() as in for example availableStationsDistancesArray.min()

So I might consider reiterating through the available nodes’ distance to dead player in an array and once I find the nearest, remove it from the array, and run through once again to now find the second closest.

It’s a dirty way to do it, but should work.

Kimedero | 2023-03-02 04:37