extends StaticBody2D # editor variables @export var max_speed = 300 @export var steer_force = 0.1 @export var acceleration = 0.0 @export var look_ahead = 75 @export var num_rays = 32 @export var driving = false # context array var ray_directions = [] var interest = [] var danger = [] var chosen_dir = Vector2.ZERO var velocity = Vector2.ZERO var current_speed = 0 # Called when the node enters the scene tree for the first time. 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[i] = Vector2.RIGHT.rotated(angle) print(ray_directions) func _physics_process(delta): if not driving: return # Code for getting the next desired direction based on the environment set_interest() set_danger() choose_direction() # example_movement(delta) own_movement(delta) func set_interest(): # Set interest in each slot based on world direction # if owner and owner.has_method("get_path_direction"): if owner and owner.has_method("get_path_next_position"): # var path_direction = owner.get_path_direction(position) var next_pos = owner.get_path_next_position(position) var path_direction = (next_pos - position).normalized() for i in num_rays: var d = ray_directions[i].rotated(rotation).dot(path_direction) interest[i] = max(0, d) # If no world path, use default interest else: set_default_interest() func set_default_interest(): # Default to moving forward for i in num_rays: var d = ray_directions[i].rotated(rotation).dot(transform.x) interest[i] = max(0, d) func set_danger(): # Cast rays to find danger directions var space_state = get_world_2d().direct_space_state var params = PhysicsRayQueryParameters2D.new() params.from = position params.exclude = [self] for i in num_rays: params.to = position + ray_directions[i].rotated(rotation) * look_ahead var result = space_state.intersect_ray(params) danger[i] = 1.0 if result else 0.0 func choose_direction(): # Eliminate interest in slots with danger for i in num_rays: if danger[i] > 0.0: interest[i] = 0.0 # Choose direction based on remaining interest chosen_dir = Vector2.ZERO for i in num_rays: chosen_dir += ray_directions[i] * interest[i] chosen_dir = chosen_dir.normalized() func example_movement(delta): var desired_velocity = chosen_dir.rotated(rotation) * max_speed velocity = velocity.lerp(desired_velocity, steer_force) rotation = velocity.angle() move_and_collide(velocity * delta) func own_movement(delta): var desired_velocity = chosen_dir.rotated(rotation) * max_speed var actual_speed = lerpf(velocity.length(), max_speed, acceleration) var actual_angle = lerp_angle(velocity.angle(), desired_velocity.angle(), steer_force) velocity = Vector2.from_angle(actual_angle) * actual_speed rotation = actual_angle move_and_collide(velocity * delta)