I implemented a rudimentary AI Movement system for a turn-based game using raycasts to determine the potential paths the AI could take. There are three Raycasts, ForwardRay, LeftRay and RightRay. If the AI is standing in a hallway, it will detect a collision for LeftRay and RightRay, but not for ForwardRay. This would indicate to the AI to move forward. The AI’s movement to the next square is instant.
The game is a dungeon crawler and right now only has hallways which fork into different directions. I noticed that under a specific circumstance an issue arises. If I have a short hallway with a staticBody3D on one end and a staticBody3D at the other, I get a strange situation.
Turn1: No viable paths, turn around 180 degrees
Turn2: Only can go forward
Turn3: Only can go forward
Turn4: No viable paths, turn around 180 degrees
Turn5: Only can go forward
Turn6: Left and Forward are viable, Right has a collision, Turn Left
Strangely it’s only on the second pass through the hallway that this occurs on. And it occurs at the same turn every time. Turn 6.
I can’t for the life of me figure this out. This enemy essentially ends up with wall hacks and just pops up behind you. Cool for a ghost, not for a slime lol.
I’ve tried adding a time delay and ForceUpdateRaycasts (Thought maybe the teleportation movement was not allowing the raycasts to update) But no cigar. I thought maybe the hallway was cursed so I moved it to a different hallway of similar length and the issue still occured.
My walls are in a Gridmap but have StaticBody3D colliders attached to them.
I have noticed sometimes when creating a new monster, the raycasts don’t detect any collisions at all, but this occurs seemingly at random for the created objects and only at the start.
I can’t seem to find anyone else having similar issues. My assumption must be that there is a better way to do the movement than with raycasts that this method isn’t often taken. So any assistance in either fixing the Raycast or recommending a different turn-based Wander function would save me from this headache.
Not any specific reason. I just assumed I could do all I needed with just the raycasts and colliders. Does the NavigationRegion3D have a way to determine if an x,y,z coordinate is within it’s region? And are they useful for grid-based movement? I’m familiar with using a NavMesh in Unreal4 for real-time movement but that’s about it.
I’ve never used it for grid-based movement, but that’s more a part of your movement controller than pathfinding. Basically, you setup a NavigationRegion3D in your level, with everything you want checked underneath it, and then add a NavigationAgent3D to anything you want to use it.
Setup for an enemy would go something like:
class_name Enemy extends CharacterBody3D
@onready var navigation_agent_3d: NavigationAgent3D = $NavigationAgent3D
@onready var player: Player = get_tree().get_first_node_in_group("Player")
@onready var rig: Node3D = $Rig
func _physics_process(delta: float) -> void:
var velocity_target := Vector3.ZERO
navigation_agent_3d.target_position = player.global_position
if rig.is_idle():
check_for_attacks()
if not navigation_agent_3d.is_target_reached():
velocity_target = get_local_navigation_direction() * speed
orient_rig(navigation_agent_3d.get_next_path_position())
navigation_agent_3d.velocity = velocity_target
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
func orient_rig(target_position: Vector3) -> void:
target_position.y = rig.global_position.y
if rig.global_position.is_equal_approx(target_position):
return
rig.look_at(target_position, Vector3.UP, true)
func get_local_navigation_direction() -> Vector3:
var destination = navigation_agent_3d.get_next_path_position()
var local_destination = destination - global_position
return local_destination.normalized()
func _on_navigation_agent_3d_velocity_computed(safe_velocity: Vector3) -> void:
if safe_velocity.length() > RUN_VELOCITY_THRESHOLD:
rig.run_weight_target = 1.0
else:
rig.run_weight_target = 0.0
velocity = safe_velocity
move_and_slide()
I recommend you find a tutorial online to learn how to set it up.