@tool extends Area2D class_name DetectionArea signal enemy_detected(enemy: Enemy) @export var radius: float = 1000: set(value): radius = value if Engine.is_editor_hint(): update_radii() @export var requires_line_of_sight: bool = true enum ActiveState {DISABLED, PREVIEW, ACTIVE} @export var active_state: ActiveState = ActiveState.PREVIEW func _ready() -> void: update_radii() func update_radii() -> void: $CollisionShape2D.shape = $CollisionShape2D.shape.duplicate() $CollisionShape2D.shape.radius = radius $PointLight2D.texture = $PointLight2D.texture.duplicate() $PointLight2D.texture.width = radius * 2 $PointLight2D.texture.height = radius * 2 func _process(delta: float) -> void: if Engine.is_editor_hint(): return for body in get_overlapping_bodies(): if body is Enemy: if !body.sighted: var sighted: bool = true if requires_line_of_sight: # perform LOS check var params: PhysicsRayQueryParameters2D = PhysicsRayQueryParameters2D.new() params.collision_mask = 0b11 params.from = global_position params.to = body.global_position var result: Dictionary = get_world_2d().direct_space_state.intersect_ray(params) sighted = result.has("collider") and result["collider"] == body if sighted: enemy_detected.emit(body) body.sighted = true