# Raycast

> Traces a line between two points on the NavMesh.

## Definition

* **Type:** Method
* **Namespace:** [Unity.AI.Navigation.LowLevel](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel.md)
* **Assembly:** UnityEngine.AIModule

## Raycast(NavMeshHit, NavLocation, Vector3, int, NativeArray\<float>)

Traces a line between two points on the NavMesh.

```csharp
public readonly NavQueryStatus Raycast(out NavMeshHit hit, NavLocation start, Vector3 targetPosition, int areaMask = -1, NativeArray<float> costs = default)
```

### Parameters

**** (\[NavMeshHit]\(/engine/6000.5/script-reference/unityengine/ai/navmeshhit)): Receives the properties of the location where the ray terminates.**** (\[NavLocation]\(/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navlocation)): The start location of the ray on the NavMesh. `start.node` must be of the type [NavNodeType.Polygon](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navnodetype/polygon.md).**** (\[Vector3]\(/engine/6000.5/script-reference/unityengine/vector3)): The desired end of the ray, in world coordinates.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): A bitmask that correlates index positions with area types. A value of 1 allows the ray to pass through that area, and a value of 0 blocks it. The default value is [NavMesh.AllAreas](/engine/6000.5/script-reference/unityengine/ai/navmesh/allareas.md).**** (\[NativeArray\<float>]\(/engine/6000.5/script-reference/unity/collections/nativearray1)): The cost multipliers for the 32 possible area types. These multipliers affect the reported ray distance. The default value is the set of area costs configured in the project settings.

### Returns

| Type                                                                                             | Description                                              |
| ------------------------------------------------------------------------------------------------ | -------------------------------------------------------- |
| [NavQueryStatus](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navquerystatus.md) | A bitfield with one of the following two main flags set: |

### Remarks

The `areaMask` bitmask uses one bit per area type, with indexes from 0 to 31. Set a bit to 1 to allow the ray to pass through that area, or to 0 to block it. The `costs` array provides multipliers for each of the 32 area types and acts on the distance reported by the ray when it crosses each area. It must be either empty or exactly 32 elements long. Otherwise, Unity throws an `ArgumentException` when this method executes in the Editor. Unlike [NavWorld.BeginFindPath](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navworld/beginfindpath.md), this method doesn't reject individual cost values below `1.0f`. For more information, refer to Areas and Costs and [NavMesh.GetAreaCost](/engine/6000.5/script-reference/unityengine/ai/navmesh/getareacost.md).

This method is similar to [NavMesh.Raycast](/engine/6000.5/script-reference/unityengine/ai/navmesh/raycast.md) and shares the same underlying implementation.

This method has the following differences:

* You can use it in parallel [jobs](/engine/6000.5/manual/scripting/optimization/job-system.md).

* It returns status flags that indicate whether the operation succeeded or failed.

* The area costs affect the reported `hit.distance`.

* It doesn't adjust the resulting `hit.position` on the vertical axis according to the HeightMesh, if one exists.

* It has a variant that also returns the list of polygons through which the ray passes.

The returned `hit.distance` represents the straight line between the start and termination point. It also takes into account the list of the provided area costs. It is the result of summing up all the distances covered by the ray over each separate area, multiplied by the cost of that respective area.

First, this method verifies that the start location is valid in the NavWorld, and maps the target point onto the NavMesh. It then traces a ray from the start point toward the target. If the computation succeeds, the `hit` data contains information about the furthest point that the ray reaches. This happens whether or not an obstruction blocks the path from the source to the target.

If the computation fails, the returned `hit` contains invalid data. Most notably, the `hit.distance` field has the value `positiveInfinity`.

If the raycast terminates on an outer edge, `hit.mask` is 0; otherwise it contains the area mask of the blocking polygon.

Use this method to check whether an agent can walk unobstructed between two points on the NavMesh. For example, if your character has an evasive dodge move that needs space, you can trace rays from the character's location in multiple directions to find a spot that the character can dodge to.

This method differs from `Physics.Raycast`. It detects all kinds of navigation obstruction, such as holes in the ground. It can also climb up slopes, if the area is navigable.

### Examples

```csharp
using UnityEngine;
using UnityEngine.AI;
using Unity.AI.Navigation.LowLevel;

public class TargetReachable : MonoBehaviour
{
    public Transform target;
    NavWorld m_NavQuery;
    NavMeshHit m_Hit;

    void OnEnable()
    {
        m_NavQuery = NavWorld.GetDefaultWorld();
    }

    void Update()
    {
        NavLocation startLocation = m_NavQuery.MapLocation(transform.position, Vector3.one, 0);
        NavQueryStatus status = m_NavQuery.Raycast(out m_Hit, startLocation, target.position, NavMesh.AllAreas);
        if ((status & NavQueryStatus.Success) != 0)
        {
            Debug.DrawLine(transform.position, target.position, m_Hit.hit ? Color.red : Color.green);

            if (m_Hit.hit)
                Debug.DrawRay(m_Hit.position, Vector3.up, Color.red);
        }
    }

    void OnDisable()
    {
        m_NavQuery.Dispose();
    }
}
```

## Raycast(NavMeshHit, NativeSlice\<NavNode>, int, NavLocation, Vector3, int, NativeArray\<float>)

Traces a line between two points on the NavMesh, and returns the list of polygons through which it passes.

```csharp
public readonly NavQueryStatus Raycast(out NavMeshHit hit, NativeSlice<NavNode> path, out int pathCount, NavLocation start, Vector3 targetPosition, int areaMask = -1, NativeArray<float> costs = default)
```

### Parameters

**** (\[NavMeshHit]\(/engine/6000.5/script-reference/unityengine/ai/navmeshhit)): Receives the properties of the location where the ray terminates.**** (\[NativeSlice\<NavNode>]\(/engine/6000.5/script-reference/unity/collections/nativeslice1)): A buffer that receives the sequence of polygons through which the ray passes.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The reported number of polygons through which the ray passes, all stored in the `path` buffer. It is never greater than `path.Length`.**** (\[NavLocation]\(/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navlocation)): The start location of the ray on the NavMesh. `start.node` must be of the type [NavNodeType.Polygon](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navnodetype/polygon.md).**** (\[Vector3]\(/engine/6000.5/script-reference/unityengine/vector3)): The desired end of the ray, in world coordinates.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): A bitmask that correlates index positions with area types. A value of 1 allows the ray to pass through that area, and a value of 0 blocks it. The default value is [NavMesh.AllAreas](/engine/6000.5/script-reference/unityengine/ai/navmesh/allareas.md).**** (\[NativeArray\<float>]\(/engine/6000.5/script-reference/unity/collections/nativearray1)): The cost multipliers for the 32 possible area types. These multipliers affect the reported ray distance. The default value is the set of area costs configured in the project settings.

### Returns

| Type                                                                                             | Description                                              |
| ------------------------------------------------------------------------------------------------ | -------------------------------------------------------- |
| [NavQueryStatus](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navquerystatus.md) | A bitfield with one of the following two main flags set: |

### Remarks

Even if the `path` buffer is too small, it still holds as many polygons as it has room for, starting from the ray's origin location. In that case, the returned status also carries the [NavQueryStatus.MoreDataAvailable](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navquerystatus/moredataavailable.md) flag.

In every other respect, this overload behaves like [NavWorld.Raycast](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navworld/raycast.md). The documentation for that overload describes in detail how this method traces the ray, how the area costs affect `hit.distance`, and what the `hit` data contains.

Additional Resources: [NavNode](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navnode.md)

### Examples

```csharp
using Unity.Collections;
using UnityEngine;
using UnityEngine.AI;
using Unity.AI.Navigation.LowLevel;

public class StraightPathFromRay : MonoBehaviour
{
    public Transform target;
    NavWorld m_NavQuery;
    NavMeshHit m_Hit;
    NativeArray<NavNode> m_Path;
    int m_PathCount;

    void OnEnable()
    {
        m_Path = new NativeArray<NavNode>(3, Allocator.Persistent);
        m_NavQuery = NavWorld.GetDefaultWorld();
    }

    void Update()
    {
        NavLocation startLocation = m_NavQuery.MapLocation(transform.position, Vector3.one, 0);
        NavQueryStatus status = m_NavQuery.Raycast(out m_Hit, m_Path, out m_PathCount,
            startLocation, target.position, NavMesh.AllAreas);
        if ((status & NavQueryStatus.Success) != 0)
        {
            // MoreDataAvailable means the ray crossed more polygons than m_Path can hold.
            // The polygons it did store are still valid, starting from the ray's origin.
            bool bufferTooSmall = (status & NavQueryStatus.MoreDataAvailable) != 0;
            Debug.DrawLine(transform.position, m_Hit.position, bufferTooSmall ? Color.black : Color.green);

            // Walk the polygons the ray passed through and outline the gate between each pair.
            for (int i = 0; i < m_PathCount - 1; i++)
            {
                if (m_NavQuery.GetPortalPoints(m_Path[i], m_Path[i + 1], out Vector3 left, out Vector3 right))
                    Debug.DrawLine(left, right, Color.cyan);
            }

            if (m_Hit.hit)
                Debug.DrawRay(m_Hit.position, Vector3.up, Color.red);
        }
    }

    void OnDisable()
    {
        m_NavQuery.Dispose();
        m_Path.Dispose();
    }
}
```
