Menu
CoddyTech

Line of Sight

Part of the Physics and Gameplay section of Coddy's Unity journey. Lesson 39 of 71.

Being close to a guard is not the same as being seen by it: a wall in between blocks the view. To test line of sight, cast a ray from the eye toward the target, and check that the first thing it hits is the target itself. The direction is the target's position minus your own, and a ray that long reaches the target:

public Transform target;

bool CanSee()
{
    Vector3 toTarget = target.position - transform.position;
    if (Physics.Raycast(transform.position, toTarget, out RaycastHit hit, toTarget.magnitude))
    {
        return hit.transform == target;
    }
    return false;
}

A security camera on a pillar logs I see you while CanSee() is true. With the target in the open, the ray's first hit is the target. With the target behind a crate, the ray hits the crate first, hit.transform is the crate's, and the answer is false. Physics.Raycast on its own returns true for the crate too, which is why the hit is compared with the target.

The target needs a collider for the ray to find it. The ray needs no normalized direction, since its length comes from maxDistance. Physics.Linecast(from, to) asks the question the other way round, whether any collider lies between two points: !Physics.Linecast(eye, target.position, wallMask) means no wall is in the way.

challenge icon

Challenge

Medium

Colour the sentry red while it can see the player, green otherwise.

  1. Write bool CanSee(): with Vector3 toPlayer = player.position - transform.position;, return false when toPlayer.magnitude > range.
  2. Then cast Physics.Raycast(transform.position, toPlayer, out RaycastHit hit, range) and return hit.transform == player; a miss returns false.
  3. In Update(), set the tower's colour to Color.red or Color.green from CanSee().

Press Play and walk behind the wall. Then Check.

Try it yourself

using UnityEngine;

public class Sentry : MonoBehaviour
{
    public Transform player;
    public float range = 8f;

    void Update()
    {
        // Red while the sentry can see the player, green otherwise.
    }
}

All lessons in Physics and Gameplay

Practice on your own: Unity playground