Sorry for spamming the forum, i’ll make this post as detailed as possible.
I’m trying to give an npc movement thats smarter than what you get out of navigationagent3D, eventually my goal is to implement context based steering. But before that, i have to make it steer in general, and for some reason i just cant seem to find the answer despite staring at the documentation and searching online.
What i need is for my script to 1. compare the direction it’s facing with another target position, and 2. if it’s not facing towards the target position, gradually turn towards it with a variable speed, steering. This is important for the context based steering later on. i dont want to just set the rotation so it snaps, and i dont want to move in the direction of the target position, i want to turn in the direction of the target position.
Extra context: What i can do is make my guy move forward, i can get the global vector3 of the target position and i can use look_at to make him snap towards the target position. What i cant do is the gradual turn, or limit the movement to x and z axis only.
Could you check if tank is facing target, if not then move tank forward in direction he is facing while rotating until he is facing target.
Sorry on phone can’t easily write sudo code at the moment. Also, not the most familiar with 3D.
You would have to figure out speed you want for his rotation. But if his facing direction is constantly being updated by rotating and you move him in facing direction it should theoretically work.
Rather than moving him to the target position you move him forward and rotate him towards target position, then once he is facing that position it is just a matter of driving.
extends CharacterBody3D
@export var turn_speed: float = 2.0 # Radians per second
@export var forward_speed: float = 5.0
# Called every physics frame
func _physics_process(delta: float) -> void:
# Get the target position (replace this with your actual target)
var target_pos = Vector3(10, 0, 10) # Example target
# Get current forward direction (assuming character faces -Z)
var current_direction = -global_transform.basis.z
# Get direction to target (ignoring Y axis)
var to_target = target_pos - global_position
to_target.y = 0 # Ignore height difference
if to_target.length() > 0.1: # Only rotate if we're not too close
# Calculate the angle difference
var target_direction = to_target.normalized()
# Get the angle between current direction and target direction
var angle_to_target = current_direction.signed_angle_to(target_direction, Vector3.UP)
# Calculate rotation step for this frame
var turn_step = turn_speed * delta
# Clamp the rotation to be no more than what we need
turn_step = min(abs(angle_to_target), turn_step) * sign(angle_to_target)
# Apply the rotation
rotate_y(turn_step)
# Move forward
var velocity = -global_transform.basis.z * forward_speed
velocity.y = 0 # Keep Y velocity unchanged
set_velocity(velocity)
move_and_slide()
# Optional debug visualization
func _draw() -> void:
# If you want to visualize the turning, you can add debug lines here
pass