【Unity】Mastering Unity's Physics.Raycast: From Basics to Advanced Ray Detection

Created: 2025-12-10

Master Physics.Raycast from basics to advanced usage. Learn LayerMask techniques to implement gaze detection and object selection.

Overview

When developing games in Unity, implementing player controls and game world interactions is unavoidable. You frequently need to accurately perform spatial "hit detection" for questions like "What is the player currently looking at?" "What object did this bullet hit?" "What's at the location where the mouse clicked?"

However, simple collision events like OnTriggerEnter or OnCollisionEnter alone cannot smartly handle these complex detections. For example, if you want to select a distant object with your gaze, you can't actually move to that object and collide with it.

This is where Physics.Raycast, a powerful feature provided by Unity's physics engine, comes in. It's a method for casting a "ray" from a point in game space in a certain direction to determine whether it hits any object with a Collider.

This article thoroughly explains Physics.Raycast, an essential technique for Unity developers, from basic usage to LayerMask techniques that beginners often struggle with, including practical C# code examples. By the end of this article, your game's interactions will have improved significantly.

Basic Concepts of Raycast: Rays and Hit Information

Physics.Raycast literally casts a "ray" to check whether it intersects with objects that have Colliders.

What is a Ray?

A Ray is defined by two elements: "Origin" and "Direction". This is expressed as a Ray struct, but it's also common to directly specify origin and direction as Vector3 arguments to the Physics.Raycast method.

What is RaycastHit?

When a Raycast collides with an object, detailed information about that collision is stored in a struct called RaycastHit. This information includes the collided object's Transform, the world coordinates of collision, the surface normal vector at the collision point, and the distance to the collision point.

Simplest Raycast Implementation

The most basic usage of Physics.Raycast is to cast a Ray forward from the camera's center to determine if it hits something.

using UnityEngine;

public class SimpleRaycaster : MonoBehaviour
{
    // Variable to store information about the object hit by Raycast
    private RaycastHit hit;

    void Update()
    {
        // Origin: Main camera position
        Vector3 origin = Camera.main.transform.position;
        // Direction: Main camera forward
        Vector3 direction = Camera.main.transform.forward;
        // Max distance: 100 meters
        float maxDistance = 100f;

        // Execute Raycast to determine if it hits something
        // Hit information is stored in the hit variable
        if (Physics.Raycast(origin, direction, out hit, maxDistance))
        {
            // Process when hit
            Debug.Log("Hit object: " + hit.collider.gameObject.name);

            // Process like changing the color of the hit object
            Renderer renderer = hit.collider.GetComponent<Renderer>();
            if (renderer != null)
            {
                renderer.material.color = Color.red;
            }
        }
        else
        {
            // Process when nothing hit
            // Debug.Log("Nothing hit.");
        }
    }
}

Physics.Raycast returns a boolean value (true or false). true means a collision occurred, and at that time, collision information is written to the variable specified with out hit.

Common Pitfall for Beginners: Using LayerMask

When using Raycast, the most confusing part for beginners is handling "LayerMask".

Problem: Hitting Unintended Objects

By default, Physics.Raycast targets all Colliders in the scene. However, if there are objects you don't want Raycast to hit—like UI elements, effects, or the player itself—having the ray hit them causes unintended behavior.

Solution: Narrow Down Targets with LayerMask

Physics.Raycast can take an optional layerMask argument. This allows fine control over which layers Raycast targets.

For example, if you want Raycast to hit only "Ground" and "Enemy" layers, create a LayerMask as follows:

using UnityEngine;

public class LayerMaskRaycaster : MonoBehaviour
{
    // Define as public variable for Inspector configuration
    [SerializeField]
    private LayerMask targetLayer;

    private RaycastHit hit;

    void Update()
    {
        // ... Origin, direction, max distance setup omitted ...
        Vector3 origin = Camera.main.transform.position;
        Vector3 direction = Camera.main.transform.forward;
        float maxDistance = 100f;

        // Specify LayerMask as 4th argument
        if (Physics.Raycast(origin, direction, out hit, maxDistance, targetLayer))
        {
            Debug.Log("Hit object in target layer: " + hit.collider.gameObject.name);
        }
    }
}

LayerMask can be easily set in Unity's Inspector window. Making this variable public or [SerializeField] allows selecting which layers to target without writing code. This is a very important technique for increasing flexibility in small to medium-scale development.

How to Ignore Specific Layers

Conversely, there are cases where you want to target "everything except specific layers (e.g., the player itself or transparent walls)." In this case, use bit operators to invert the LayerMask.

For example, to ignore the "Ignore Raycast" layer, use the following code:

using UnityEngine;

public class IgnoreLayerRaycaster : MonoBehaviour
{
    void Update()
    {
        // Get bit value of layer to ignore
        int ignoreLayer = LayerMask.NameToLayer("Ignore Raycast");

        // Invert (NOT operation) the bit of the layer to ignore from all layers
        // ~ means bit inversion
        int layerMask = ~ (1 << ignoreLayer);

        Vector3 origin = transform.position;
        Vector3 direction = transform.forward;
        float maxDistance = 10f;

        // Apply inverted LayerMask
        if (Physics.Raycast(origin, direction, out RaycastHit hit, maxDistance, layerMask))
        {
            Debug.DrawRay(origin, direction * hit.distance, Color.green);
            Debug.Log("Hit object outside ignore layer: " + hit.collider.gameObject.name);
        }
        else
        {
            Debug.DrawRay(origin, direction * maxDistance, Color.white);
        }
    }
}

This ~ (1 << ignoreLayer) notation is a very frequently used idiom when working with Unity's LayerMask, so be sure to remember it.

Summary

Physics.Raycast is the foundation technology for implementing interactions in Unity. Here are the key points covered in this article:

  1. Raycast is ray-based hit detection: Physics.Raycast casts a Ray with an origin and direction to detect collisions with Colliders.
  2. Hit information is stored in RaycastHit: When a collision succeeds, detailed information like the hit object name, coordinates, and distance is obtained through the out RaycastHit argument.
  3. Narrow down targets with LayerMask: To prevent hitting unintended objects, it's important to explicitly specify which layers Raycast targets using the LayerMask argument.
  4. Use bit inversion to ignore specific layers: To ignore specific layers, use the bit operator technique ~ (1 << LayerMask.NameToLayer("LayerName")).
  5. Visualize with Debug.DrawRay: To verify Raycast is working correctly, develop the habit of visualizing the ray's trajectory in the scene view using Debug.DrawRay.

By applying this knowledge and code examples, the precision of object manipulation and gaze detection in your game development will improve dramatically. Please try it in your own projects.