# Raycast

> Trace a line between two points on the NavMesh.

## Definition

* **Type:** Method
* **Namespace:** [UnityEngine.Experimental.AI](/engine/6000.3/script-reference/unityengine/experimental/ai.md)
* **Assembly:** UnityEngine.AIModule

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

Trace a line between two points on the NavMesh.

> **Warning:**
>
> **Deprecated.** The experimental NavMeshQuery struct has been deprecated without replacement.

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

### Parameters

**** (\[NavMeshHit]\(/engine/6000.3/script-reference/unityengine/ai/navmeshhit)): Holds the properties of the raycast resulting location.**** (\[NavMeshLocation]\(/engine/6000.3/script-reference/unityengine/experimental/ai/navmeshlocation)): The start location of the ray on the NavMesh. `start.polygon` must be of the type [NavMeshPolyTypes.Ground](/engine/6000.3/script-reference/unityengine/experimental/ai/navmeshpolytypes/ground.md).**** (\[Vector3]\(/engine/6000.3/script-reference/unityengine/vector3)): The desired end of the ray, in world coordinates.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): Bitmask that correlates index positions with area types.  The index goes from 0 to 31. In each relevant index position, you have to set the value to either 1 or 0. 1 indicates area types that the ray can pass through. 0 indicates area types that block the ray. This parameter is optional. If you leave out this parameter, it defaults to [NavMesh.AllAreas](/engine/6000.3/script-reference/unityengine/ai/navmesh/allareas.md). To learn more, see: [Areas and Costs](https://docs.unity3d.com/Packages/com.unity.ai.navigation@2.0/manual/AreasAndCosts.html).**** (\[NativeArray\<float>]\(/engine/6000.3/script-reference/unity/collections/nativearray1)): Array of custom cost values for all of the 32 possible area types. They act as multipliers to the distance reported by the ray when crossing various areas. This parameter is optional. If you omit it, it defaults to the area costs that you configured in the Project settings. To learn more, see [NavMesh.GetAreaCost](/engine/6000.3/script-reference/unityengine/ai/navmesh/getareacost.md).

### Returns

| Type                                                                                              | Description                                                                |
| ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| [PathQueryStatus](/engine/6000.3/script-reference/unityengine/experimental/ai/pathquerystatus.md) | `Success` if the ray can be correctly traced using the provided arguments. |

### Remarks

This method is similar to [NavMesh.Raycast](/engine/6000.3/script-reference/unityengine/ai/navmesh/raycast.md), both of them sharing the same underlying implementation.

The properties that make this one different are:

* it can be used in parallel [jobs](/engine/6000.3/manual/scripting/optimization/job-system.md);

* it returns status flags indicating whether the operation succeeded or failed;

* the reported `hit.distance` is affected by the area costs;

* the resulting `hit.position` is not adjusted on the vertical axis according to the [HeightMesh](https://docs.unity3d.com/Packages/com.unity.ai.navigation@2.0/manual/HeightMesh.html), if that exists;

* it has the variant described below that returns also 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, the start location is verified to be valid in the NavMeshWorld, and the target point is mapped on the NavMesh. Then, a ray is traced from the start point towards the target. If the computation is successful, the `hit` data is filled with information about the furthest point that the ray has reached. This happens regardless of whether the path from the source to target has been obstructed.

If the computation fails, the returned `hit` is filled with invalid data. Most notably, the `hit.distance` field gets 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.

You can use this function to check if 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 shoot a ray from the character's location to multiple directions. This finds a spot where the character can dodge to.

The [NavMeshQuery.Raycast](/engine/6000.3/script-reference/unityengine/experimental/ai/navmeshquery/raycast.md) is different from the Physics raycast. The NavMeshQuery.Raycast can detect all kinds of navigation obstructions, for example holes in the ground. It can also climb up slopes, if the area is navigable.

### Examples

```csharp
// TargetReachable
using Unity.Collections;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Experimental.AI;

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

    void OnEnable()
    {
        m_NavQuery = new NavMeshQuery(NavMeshWorld.GetDefaultWorld(), Allocator.Persistent);
    }

    void Update()
    {
        var startLocation = m_NavQuery.MapLocation(transform.position, Vector3.one, 0);
        var status = m_NavQuery.Raycast(out m_Hit, startLocation, target.position, NavMesh.AllAreas, new NativeArray<float>());
        if ((status & PathQueryStatus.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\<PolygonId>, int, NavMeshLocation, Vector3, int, NativeArray\<float>)

Trace a line between two points on the NavMesh, and return the list of polygons through which it passed.

> **Warning:**
>
> **Deprecated.** The experimental NavMeshQuery struct has been deprecated without replacement.

```csharp
public PathQueryStatus Raycast(out NavMeshHit hit, NativeSlice<PolygonId> path, out int pathCount, NavMeshLocation start, Vector3 targetPosition, int areaMask = -1, NativeArray<float> costs = default)
```

### Parameters

**** (\[NavMeshHit]\(/engine/6000.3/script-reference/unityengine/ai/navmeshhit)): Holds the properties of the raycast resulting location.**** (\[NativeSlice\<PolygonId>]\(/engine/6000.3/script-reference/unity/collections/nativeslice1)): A buffer that will be filled with 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 has passed, all stored in the `path` buffer. It will not be greater than `path.Length`.**** (\[NavMeshLocation]\(/engine/6000.3/script-reference/unityengine/experimental/ai/navmeshlocation)): The start location of the ray on the NavMesh. `start.polygon` must be of the type [NavMeshPolyTypes.Ground](/engine/6000.3/script-reference/unityengine/experimental/ai/navmeshpolytypes/ground.md).**** (\[Vector3]\(/engine/6000.3/script-reference/unityengine/vector3)): The desired end of the ray, in world coordinates.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): A bitfield that specifies which NavMesh areas can be traversed when the ray is traced. This parameter is optional. If you do not fill out this parameter, it defaults to [NavMesh.AllAreas](/engine/6000.3/script-reference/unityengine/ai/navmesh/allareas.md).**** (\[NativeArray\<float>]\(/engine/6000.3/script-reference/unity/collections/nativearray1)): Cost multipliers that affect the distance reported by the ray over different area types. This parameter is optional. If you omit it, it defaults to the area costs that you configured in the Project settings.

### Returns

| Type                                                                                              | Description                                                                |
| ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| [PathQueryStatus](/engine/6000.3/script-reference/unityengine/experimental/ai/pathquerystatus.md) | `Success` if the ray can be correctly traced using the provided arguments. |

### Remarks

Even if the `path` buffer is too small it will still hold as many polygons as it has room for, starting from the ray's origin location.

Additional Resources: [PolygonId](/engine/6000.3/script-reference/unityengine/experimental/ai/polygonid.md).

### Examples

```csharp
// StraightPathFromRay
using Unity.Collections;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Experimental.AI;

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

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

    void Update()
    {
        var startLocation = m_NavQuery.MapLocation(transform.position, Vector3.one, 0);
        PathQueryStatus status = m_NavQuery.Raycast(out m_Hit, m_Path, out m_PathCount, startLocation, target.position, NavMesh.AllAreas, new NativeArray<float>());
        if ((status & PathQueryStatus.Success) != 0)
        {
            var bufferTooSmall = (status & PathQueryStatus.BufferTooSmall) != 0;
            Debug.DrawLine(transform.position, m_Hit.position, bufferTooSmall ? Color.black : Color.green);

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

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