4.3.stable.official
A physics process in another script constantly runs update_target_position through a group call and sets the Vector3 “go” to our target position, thats plugged into the context array, and my dude freaks out. sometimes it snakes around in big circles, other times gets stuck on the wall its supposed to avoid, and on a rare occasion actually makes it where it’s supposed to go. It’s kind of doing what it’s supposed to sometimes, but clearly something about this is very wrong, and i have no idea what. the actual movement script, what comes after choose_direction() in the physics process, works fine when a static coordinate is plugged into it, suggesting that the issue is in the arrays. problem is, as far as i can tell, those work correctly too, according to debug
var ray_directions : PackedVector3Array = []
var interest = []
var danger = []
@export var look_ahead = 4 # The length of the rays, ive fiddled with this number a lot with no results
@export var num_rays = 8
var chosen_dir = Vector3.ZERO
var go = Vector3.ZERO
func _ready():
interest.resize(num_rays)
danger.resize(num_rays)
ray_directions.resize(num_rays)
for i in num_rays:
var angle = i * 2 * PI / num_rays
ray_directions.set(i, Vector3.FORWARD.rotated(Vector3.UP, angle))
func update_target_position(target_position) -> void:
# This target position is the position of my click, set by a group call from another script
go = target_position - global_position
go = go.normalized()
func _physics_process(delta):
# Populate context arrays
set_interest()
set_danger()
choose_direction()
var current_direction = -global_transform.basis.z # Get current forward direction (assuming character faces -Z) # Get direction to target (ignoring Y axis)
# Get direction to target (ignoring Y axis)
var to_target = chosen_dir - global_position.normalized()
to_target.y = 0 # Ignore height difference
# 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)
if angle_to_target != 0: # If we're not rotated enough
if current_steer < max_steer: # Accelerate steering
current_steer += steer_accel * delta
else: # If we are rotated enough
current_steer = 0
# Calculate rotation step for this frame
var turn_step = current_steer * 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
if current_velocity < max_speed:
current_velocity += accel * delta
velocity = -global_transform.basis.z * current_velocity
velocity.y = 0.0
move_and_collide(velocity)
func set_interest():
for i in num_rays: # This seems to set interest correctly
var d = ray_directions[i].normalized().dot(go)
interest[i] = d
func set_danger():
var space_state = get_world_3d().direct_space_state
for i in num_rays: #shoot some rays
var query = PhysicsRayQueryParameters3D.create(position, position + ray_directions[i] * look_ahead)
query.exclude = [self]
var result = space_state.intersect_ray(query)
danger[i] = 5 if result else 0 # in debug the danger array returns a 5 in the direction of the wall its running against so this works
func choose_direction():
for i in num_rays:
interest[i] = interest[i] - danger[i]
chosen_dir = Vector3.ZERO
for i in num_rays:
chosen_dir += ray_directions[i] * interest[i]
chosen_dir = chosen_dir.normalized()
It’s a big chunk, so thanks a lot if you do decide to take a look at it