Quick answer: Disable the source enemy’s collisions just for the LoS check (then re-enable), or set the obstacle list to specific obstacle objects (walls only), not the EnemyFamily.

A stealth game uses Line of Sight to let enemies spot the player. EnemyFamily is in the LoS “blocks sight” obstacle list (because enemies block each other). LoS always returns false even with clear path. Source enemy blocks itself.

Cause

The LoS ray starts inside the source enemy’s collision box. Since the family is an obstacle, the ray immediately hits and reports blocked.

Fix 1: Temporarily Disable Collisions

For each EnemyFamily
    EnemyFamily → Set collisions Disabled
    EnemyFamily has LoS to Player
        → RaiseAlarm
    EnemyFamily → Set collisions Enabled

Disable for the check, re-enable immediately. Cheap, reliable. Works because the LoS check is synchronous within the same tick.

Fix 2: Restrict Obstacle List

If “enemies block each other’s sight” isn’t critical to gameplay, simplify:

Simpler, no per-tick toggling.

Fix 3: Offset LoS Origin

Position the LoS check from a slightly-outside point:

System → Pick by comparison: distance(EnemyFamily.X+8*cos(EnemyFamily.angle), ..., Player.X, ...) < sight_range

Hacky; the “disable collision” approach is cleaner.

Verifying

With several enemies and a player: each enemy in line of sight reports true. Walls block. Enemies in the way of another enemy’s LoS block according to your chosen rule.

“Self-collision is a perennial issue for vision rays. Disable-then-restore is the standard fix.”

For stealth games, an enemy not blocking another’s sight feels okay — players don’t notice. Simplify and ship.