[Godot 4] How to handle flying enemies with NavigationRegion3D

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

Hey Everyone!

I am currently working on a Dungeon Crawler, where I want some flying bat enemy to follow the player. I am using a NavigationRegion3D Node with a baked Navigation Mesh and my GridMap node for the world is attached to that node.

Everything is working fine, but the enemy is staying very low on the floor. First I thought this is because the reference point of my player is at the bottom of the player model, but I have now added a Marker3D node in my player scene (at camera height) and set that as target.

I feel like the enemy is bound to the mesh that is rather low on the floor. Ideally i would like the enemy to randomly choose a height to fly at (within a certain range), but for now it would be fine to just offset the height of the enemy by a fixed amount.

This is my code to send the bat towards the player:

func _physics_process(delta):

var player_position = player.global_transform.origin
get_tree().call_group("enemies", "update_target_location",player_position)

print(player_position)

The _physics_process and update_target_location function in the enemy looks like this:

func _physics_process(delta):
var current_location = global_transform.origin
var next_location = nav_agent.get_next_location()
var new_velocity = (next_location - current_location).normalized() * SPEED

velocity = new_velocity
move_and_slide()


var player_position = player.global_transform.origin
look_at(player_position)
self.rotate_object_local(Vector3(0,1,0), 3.14)

func update_target_location(target_location):
nav_agent.set_target_location(target_location)

Variables here are:

@onready var nav_agent = $NavigationAgent3D
@onready var anim_player = $AnimationPlayer
@onready var player = $"../PlayerCharacter"
var SPEED = 3.0

Please let me know if you need further details. Thank you very much in advance!

Best,
Malthur123

:bust_in_silhouette: Reply From: smix8

Nothing is binding you to the navigation mesh surface, you are the puppet master. If you want a “flying” unit to have height variation on the y-axis do so in your movement code and add / reduce the height with an offset. Calculate your next position first as if the unit is on ground and then add your offset to the y-axis of the visual or physics representation of the unit.

This “flying” behavior is completely unrelated to the actual pathfinding system. Apart from very technically specific games that use voxel navigation a flying unit in most games e.g. RTS games, is just a normal “ground” unit where the pathfinding still happens at ground level with a mostly flat navigation mesh and the visual or physics representation of the unit is then offset on the y-axis.