Help finding nearest object(and working out the proper code I just realized I need this done in the next six days)

Godot Version

4.2.1

Question

I am new to this and am trying to make a 2d monster raiser where bats will fly around and try to kill your (characterbody2d)livestock. Is there a way I could make the bats fly to the nearest animal?

The simplest approach is to compare the distance between a bat and each livestock animal.

# Pretend that this is an array full of CharacterBody2D node references
var livestock = []
var bat = this   # Again, pretend this is a reference to your bat object

var lowest_distance = INF    # Initialized as infinity to avoid unintended behaviour at large distances
var closest_animal
for animal in livestock:
    var distance = animal.global_position - bat.global_position
    
    # Check whether the distance to the animal is lower
    # than the previously checked animals
    if distance < lowestDistance:
        closest_animal = animal       # Set this animal as the closest animal
        lowest_distance = distance    # Update the lowest distance found

# This is an if-statement that evaluates whether an animal was found
# It will usually only run if there are no valid animal instances
if !is_instance_valid(closest_animal) or lowest_distance == INF:
    WARN_PRINT("No valid animal found to follow!");
    return

# Insert your own movement code here
# For example:
# velocity = (closest_animal.global_position - bat.global_position).normalized()
# move_and_slide()

Disclaimer: I don’t use GDScript myself, so take the code above with a grain of salt.

1 Like

The code seems to check out but what does it mean by array full of references? Would I have to have a bunch of references to the different creatures? If so, would that even work if i were to spawn in more livestock?

Never mind no matter what way I put it the code does not seem to work.

Small corection to the above code, you should check distance like this:
var distance = animal.global_position.distance_squared_to(bat.global_position)

In GDScript comparing Vectors with < compares their individual elements, not their length, so you can’t compare distances that way.

The array is just an array of any objects (animals) you want the bats to consider attacking.

1 Like

It says unexpected for in class body and unexpected if in class body. What should I do?

Well you should put it in a function, something like:

# Pretend that this is an array full of CharacterBody2D node references
var livestock = []
var bat = $bat   # Again, pretend this is a reference to your bat object

func _process():
    var closest_animal = find_closest_animal()

    # Insert your own movement code here
    # For example:
    # velocity = (closest_animal.global_position - bat.global_position).normalized()
    # move_and_slide()

func find_closest_animal():
    var lowest_distance = INF    # Initialized as infinity to avoid unintended behaviour at large distances
    var closest_animal
    for animal in livestock:
        var distance = animal.global_position.distance_squared_to(bat.global_position)
    
        # Check whether the distance to the animal is lower
        # than the previously checked animals
        if distance < lowestDistance:
            closest_animal = animal       # Set this animal as the closest animal
            lowest_distance = distance    # Update the lowest distance found
    
    # This is an if-statement that evaluates whether an animal was found
    # It will usually only run if there are no valid animal instances
    if !is_instance_valid(closest_animal) or lowest_distance == INF:
        WARN_PRINT("No valid animal found to follow!");
        return

    return closest_animal
    

1 Like

@Monday Thanks for fixing the example.
My mind doesn’t work too well with dynamic typing :sweat_smile:

@thepiglin83 To answer your question regarding having an array full of references, it was really just a variable I put in to complete the example code. As long as you can get a full list of your “livestock”, that’s all that matters.

1 Like