# MoveLocations

> Translates a series of NavMesh locations to other positions without losing contact with the surface.

## Definition

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

## MoveLocations(NativeSlice\<NavLocation>, NativeSlice\<Vector3>, NativeSlice\<int>)

Translates a series of NavMesh locations to other positions without losing contact with the surface.

```csharp
public readonly void MoveLocations(NativeSlice<NavLocation> locations, NativeSlice<Vector3> destinations, NativeSlice<int> areaMasks)
```

### Parameters

**** (\[NativeSlice\<NavLocation>]\(/engine/6000.5/script-reference/unity/collections/nativeslice1)): The array of positions to move across the NavMesh surface. At the end of the method call, this array contains the resulting locations.**** (\[NativeSlice\<Vector3>]\(/engine/6000.5/script-reference/unity/collections/nativeslice1)): The world positions to use as movement targets for each of the locations.**** (\[NativeSlice\<int>]\(/engine/6000.5/script-reference/unity/collections/nativeslice1)): The filters for the areas that each of the movements can traverse.

### Remarks

This method performs the same operation as [NavWorld.MoveLocation](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navworld/movelocation.md), but acts sequentially on a batch of locations, given their respective destinations and area filters. All three array parameters must have the same length. Otherwise, Unity throws an `ArgumentException` when this method executes in the Editor.

This method writes the results in place, into the `locations` array.

You can safely call this operation while a separate pathfinding query is in progress on the same query buffer instance.

Additional Resources: [NavWorld.MoveLocation](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navworld/movelocation.md), [NavLocation](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navlocation.md)

### Examples

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

public class MoveLocationsExample : MonoBehaviour
{
    public Transform[] agents;
    public Transform[] targets;

    void Update()
    {
        using NavWorld world = NavWorld.GetDefaultWorld();
        NativeArray<NavLocation> locations = new NativeArray<NavLocation>(agents.Length, Allocator.Temp);
        NativeArray<Vector3> destinations = new NativeArray<Vector3>(agents.Length, Allocator.Temp);
        NativeArray<int> masks = new NativeArray<int>(agents.Length, Allocator.Temp);

        for (int i = 0; i < agents.Length; i++)
        {
            locations[i] = world.MapLocation(agents[i].position, Vector3.one, 0);
            destinations[i] = targets[i].position;
            masks[i] = NavMesh.AllAreas;
        }

        world.MoveLocations(locations, destinations, masks);

        for (int i = 0; i < agents.Length; i++)
            agents[i].position = locations[i].position;

        locations.Dispose();
        destinations.Dispose();
        masks.Dispose();
    }
}
```

## MoveLocations(NativeSlice\<NavLocation>, NativeSlice\<Vector3>, int)

Translates a series of NavMesh locations to other positions without losing contact with the surface, given one common area filter for all of them.

```csharp
public readonly void MoveLocations(NativeSlice<NavLocation> locations, NativeSlice<Vector3> destinations, int areaMask = -1)
```

### Parameters

**** (\[NativeSlice\<NavLocation>]\(/engine/6000.5/script-reference/unity/collections/nativeslice1)): The array of positions to move across the NavMesh surface. At the end of the method call, this array contains the resulting locations.**** (\[NativeSlice\<Vector3>]\(/engine/6000.5/script-reference/unity/collections/nativeslice1)): The world positions to use as movement targets for each of the locations.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The filter for the areas that all of the movements can traverse. The default value is [NavMesh.AllAreas](/engine/6000.5/script-reference/unityengine/ai/navmesh/allareas.md).

### Remarks

This method performs the same operation as [NavWorld.MoveLocations](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navworld/movelocations.md), but applies the same area filter to all the movements. The `locations` and `destinations` arrays must have the same length. Otherwise, Unity throws an `ArgumentException` when this method executes in the Editor.

You can safely call this operation while a separate pathfinding query is in progress on the same query buffer instance.

Additional Resources: [NavWorld.MoveLocation](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navworld/movelocation.md), [NavLocation](/engine/6000.5/script-reference/unity/ai/navigation/lowlevel/navlocation.md)

### Examples

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

public class MoveLocationsSharedMaskExample : MonoBehaviour
{
    public Transform[] agents;
    public Transform[] targets;

    void Update()
    {
        using NavWorld world = NavWorld.GetDefaultWorld();
        NativeArray<NavLocation> locations = new NativeArray<NavLocation>(agents.Length, Allocator.Temp);
        NativeArray<Vector3> destinations = new NativeArray<Vector3>(agents.Length, Allocator.Temp);

        for (int i = 0; i < agents.Length; i++)
        {
            locations[i] = world.MapLocation(agents[i].position, Vector3.one, 0);
            destinations[i] = targets[i].position;
        }

        world.MoveLocations(locations, destinations, NavMesh.AllAreas);

        for (int i = 0; i < agents.Length; i++)
            agents[i].position = locations[i].position;

        locations.Dispose();
        destinations.Dispose();
    }
}
```

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

public class MoveLocationsSliceExample : MonoBehaviour
{
    public Transform[] agents;
    public Transform target;

    // How many agents advance per frame. The others keep their location until their turn.
    public int agentsPerFrame = 16;

    NavWorld m_World;
    NativeArray<NavLocation> m_Locations;
    NativeArray<Vector3> m_Destinations;
    int m_NextAgent;

    void OnEnable()
    {
        m_World = NavWorld.GetDefaultWorld();
        m_Locations = new NativeArray<NavLocation>(agents.Length, Allocator.Persistent);
        m_Destinations = new NativeArray<Vector3>(agents.Length, Allocator.Persistent);

        // Project every agent onto the NavMesh once, then keep the locations up to date by
        // moving them, which is cheaper than re-projecting them every frame.
        for (int i = 0; i < agents.Length; i++)
            m_Locations[i] = m_World.MapLocation(agents[i].position, Vector3.one, 0);
    }

    void Update()
    {
        int remaining = agents.Length - m_NextAgent;
        int count = Mathf.Clamp(agentsPerFrame, 0, remaining);
        if (count == 0)
            return;

        for (int i = m_NextAgent; i < m_NextAgent + count; i++)
            m_Destinations[i] = target.position;

        // Both MoveLocations overloads take a NativeSlice, so you can hand them a window into
        // a persistent array and spread a large crowd over several frames.
        NativeSlice<NavLocation> movedLocations = new NativeSlice<NavLocation>(m_Locations, m_NextAgent, count);
        NativeSlice<Vector3> movedDestinations = new NativeSlice<Vector3>(m_Destinations, m_NextAgent, count);
        m_World.MoveLocations(movedLocations, movedDestinations, NavMesh.AllAreas);

        // The results are written back in place, so read them from the same slice.
        for (int i = 0; i < count; i++)
            agents[m_NextAgent + i].position = movedLocations[i].position;

        m_NextAgent += count;
        if (m_NextAgent >= agents.Length)
            m_NextAgent = 0;
    }

    void OnDisable()
    {
        m_Destinations.Dispose();
        m_Locations.Dispose();
        m_World.Dispose();
    }
}
```
