# SetVertices

> Assigns a new vertex positions array.

## Definition

* **Type:** Method
* **Namespace:** [UnityEngine](/engine/6000.7/script-reference/unityengine.md)
* **Assembly:** UnityEngine.CoreModule

## SetVertices(List\<Vector3>)

Assigns a new vertex positions array.

```csharp
public void SetVertices(List<Vector3> inVertices)
```

### Parameters

**** (\[List\<Vector3>]\(https\://learn.microsoft.com/dotnet/api/system.collections.generic.list-1)): The vertex positions to copy, which replaces existing [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) vertices and sets the new vertex count.

### Remarks

Use this method to assign a complete set of vertex positions to the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md). This is a fundamental operation for defining or modifying the shape of a mesh procedurally.

**Data Handling:** When you provide a container, Unity copies the position data from your container into the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) internal storage.

* You can safely modify your original container after calling [Mesh.SetVertices](/engine/6000.7/script-reference/unityengine/mesh/setvertices.md) without affecting the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) data.
* You can reuse the same source container to set data for multiple different [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) objects.
* The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) does not keep a reference to your original container (especially relevant for managed arrays and lists).

**Vertex Count:** Calling this method overwrites all existing vertex positions. The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) vertex count (see [Mesh.vertexCount](/engine/6000.7/script-reference/unityengine/mesh/vertexcount.md)) will be adjusted to match the number of elements in the `inVertices` container you provide. If you subsequently set other per-vertex data (like normals or UVs), ensure their count matches the new vertex count.

This method is often used as the underlying implementation for the [Mesh.vertices](/engine/6000.7/script-reference/unityengine/mesh/vertices.md) property setter. For frequent updates, consider calling [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md) first, which may improve performance by optimizing the underlying GPU buffer strategy.

```csharp
using UnityEngine;
using Unity.Collections;

// This script demonstrates how to create a simple quad mesh from scratch.
// Attach this script to an empty GameObject. It will create a Mesh and
// assign it to the MeshFilter, and add a default material to the MeshRenderer.
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SetVerticesFullExample : MonoBehaviour
{
    private Material m_Material;
    private Mesh m_Mesh;

    void Start()
    {
        // Create a new mesh object.
        m_Mesh = new Mesh();
        m_Mesh.name = "Procedural Quad";

        // Define the vertex and triangle data.
        var vertices = new NativeArray<Vector3>(4, Allocator.Temp);
        vertices[0] = new Vector3(-1, 0, -1);
        vertices[1] = new Vector3(-1, 0,  1);
        vertices[2] = new Vector3( 1, 0,  1);
        vertices[3] = new Vector3( 1, 0, -1);

        var triangles = new NativeArray<int>(6, Allocator.Temp);
        triangles[0] = 0; triangles[1] = 1; triangles[2] = 2; // First triangle
        triangles[3] = 0; triangles[4] = 2; triangles[5] = 3; // Second triangle

        // Populate the mesh with the data.
        m_Mesh.SetVertices(vertices);
        m_Mesh.SetIndices(triangles, MeshTopology.Triangles, 0);

        // Dispose of the NativeArrays now that the data is in the mesh.
        vertices.Dispose();
        triangles.Dispose();

        // Finalize the mesh state for rendering.
        m_Mesh.RecalculateNormals();
        m_Mesh.RecalculateBounds();

        // Get the required components and assign the fully constructed mesh and a material.
        var meshFilter = GetComponent<MeshFilter>();
        meshFilter.sharedMesh = m_Mesh;

        var renderer = GetComponent<MeshRenderer>();
        if (renderer.sharedMaterial == null)
        {
            m_Material  = new Material(Shader.Find("Unlit/Color")); 
            renderer.sharedMaterial = m_Material;
        }
    }

    void OnDestroy()
    {
        // Destroy the mesh when the component is destroyed to prevent memory leaks.
        if (m_Mesh != null)
            Destroy(m_Mesh);
        if (m_Material != null)
            Destroy(m_Material);
    }
}
```

Additional Resources: [Mesh.vertices](/engine/6000.7/script-reference/unityengine/mesh/vertices.md), [Mesh.vertexCount](/engine/6000.7/script-reference/unityengine/mesh/vertexcount.md), [Mesh.SetIndices](/engine/6000.7/script-reference/unityengine/mesh/setindices.md), [Mesh.SetNormals](/engine/6000.7/script-reference/unityengine/mesh/setnormals.md), [Mesh.SetUVs](/engine/6000.7/script-reference/unityengine/mesh/setuvs.md), [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md), [Mesh.RecalculateNormals](/engine/6000.7/script-reference/unityengine/mesh/recalculatenormals.md).

## SetVertices(List\<Vector3>, int, int, MeshUpdateFlags)

Sets the vertex positions for the entire [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) using data copied from a specific slice of a source container.

```csharp
public void SetVertices(List<Vector3> inVertices, int start, int length, MeshUpdateFlags flags)
```

### Parameters

**** (\[List\<Vector3>]\(https\://learn.microsoft.com/dotnet/api/system.collections.generic.list-1)): The vertex positions to copy, which replaces existing [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) vertices and sets the new vertex count.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The zero-based index within `inVertices` where the slice of data to be copied begins.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The number of vertex positions to copy from `inVertices`, starting from the `start` index, which also becomes the new vertex count of the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md).**** (\[MeshUpdateFlags]\(/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags)): Optional flags to control behavior after setting the vertices, such as skipping automatic bounds recalculation (default is [MeshUpdateFlags.Default](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags/default.md)).

### Remarks

Use this method to assign a complete set of vertex positions to the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md), sourcing the data from a portion of a larger array, list, or `NativeArray`.

**Data Handling and Slicing:** This method behaves similarly to the full container overload, but only uses elements from the `inVertices` container starting at the `start` index and taking @@length@ number of elements. Unity copies this slice of position data into the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) internal storage.

* As with the full overload, you can safely modify the original source container after calling this method without affecting the `Mesh` data.
* The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) does not keep a reference to your original container.
* Ensure that `start` and `length` define a valid range within the bounds of the `inVertices` container.

**Mesh Update Flags:** The `flags` parameter allows you to control post-update operations. For example, using [MeshUpdateFlags.DontRecalculateBounds](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags/dontrecalculatebounds.md) can prevent the automatic (and potentially costly) recalculation of the mesh bounds if you intend to set them manually later or know they haven't changed significantly. See [MeshUpdateFlags](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags.md) for details.

For frequent updates using slices, consider calling [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md) first to potentially improve performance.

```csharp
using UnityEngine;
using Unity.Collections;
using UnityEngine.Rendering;

// This script demonstrates how to set mesh vertices using a slice of a larger data array.
// It creates two quads' worth of vertex data but only displays one at a time.
// Use the "Start Index Group" slider in the Inspector to switch between them.
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SetVerticesPartialExample : MonoBehaviour
{
    [Range(0,1)]
    public int startIndexGroup = 0;

    private Mesh m_Mesh;
    private NativeArray<Vector3> m_AllVertices;
    private int m_PreviousIndexGroup = -1;

    void Start()
    {
        m_Mesh = new Mesh();
        m_Mesh.name = "Partial Vertices Mesh";

        // Create a persistent NativeArray containing data for multiple potential quads.
        m_AllVertices = new NativeArray<Vector3>(8, Allocator.Persistent);

        // Quad 1 vertices (group 0)
        m_AllVertices[0] = new Vector3(-1, 0, -1);
        m_AllVertices[1] = new Vector3(-1, 0,  1);
        m_AllVertices[2] = new Vector3( 1, 0,  1);
        m_AllVertices[3] = new Vector3( 1, 0, -1);

        // Quad 2 vertices (group 1), offset on X axis
        m_AllVertices[4] = new Vector3( 2, 0, -1);
        m_AllVertices[5] = new Vector3( 2, 0,  1);
        m_AllVertices[6] = new Vector3( 4, 0,  1);
        m_AllVertices[7] = new Vector3( 4, 0, -1);

        var renderer = GetComponent<MeshRenderer>();
        renderer.material = new Material(Shader.Find("Unlit/Color"));

        var meshFilter = GetComponent<MeshFilter>();
        meshFilter.mesh = m_Mesh;
    }

    void Update()
    {
        if (m_PreviousIndexGroup == startIndexGroup)
            return;

        m_PreviousIndexGroup = startIndexGroup;

        // Set the mesh vertices using a slice of the full data array.
        int dataLength = 4;
        int startIndex = startIndexGroup * dataLength;

        // Copy the slice from m_AllVertices into the Mesh.
        m_Mesh.SetVertices(m_AllVertices, startIndex, dataLength, MeshUpdateFlags.DontRecalculateBounds);

        // Define the triangles for a single quad using a NativeArray.
        var triangles = new NativeArray<int>(6, Allocator.Temp);
        triangles[0] = 0; triangles[1] = 1; triangles[2] = 2;
        triangles[3] = 0; triangles[4] = 2; triangles[5] = 3;
        m_Mesh.SetIndices(triangles, MeshTopology.Triangles, 0);
        triangles.Dispose();

        // Recalculate bounds and normals manually.
        m_Mesh.RecalculateBounds();
        m_Mesh.RecalculateNormals();

        Debug.Log($"Mesh updated to show vertex group {startIndexGroup}.");
    }

    void OnDestroy()
    {
        // Dispose the persistent NativeArray and destroy the mesh to prevent memory leaks.
        if (m_AllVertices.IsCreated)
            m_AllVertices.Dispose();

        if (m_Mesh != null)
            Destroy(m_Mesh);
    }
}
```

Additional Resources: [Mesh.vertices](/engine/6000.7/script-reference/unityengine/mesh/vertices.md), [Mesh.vertexCount](/engine/6000.7/script-reference/unityengine/mesh/vertexcount.md), [Mesh.SetIndices](/engine/6000.7/script-reference/unityengine/mesh/setindices.md), [Mesh.SetNormals](/engine/6000.7/script-reference/unityengine/mesh/setnormals.md), [Mesh.SetUVs](/engine/6000.7/script-reference/unityengine/mesh/setuvs.md), [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md), [MeshUpdateFlags](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags.md), [Mesh.UploadMeshData](/engine/6000.7/script-reference/unityengine/mesh/uploadmeshdata.md).

## SetVertices(Vector3\[])

Assigns a new vertex positions array.

```csharp
public void SetVertices(Vector3[] inVertices)
```

### Parameters

**** (\[Vector3\[]]\(/engine/6000.7/script-reference/unityengine/vector3)): The vertex positions to copy, which replaces existing [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) vertices and sets the new vertex count.

### Remarks

Use this method to assign a complete set of vertex positions to the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md). This is a fundamental operation for defining or modifying the shape of a mesh procedurally.

**Data Handling:** When you provide a container, Unity copies the position data from your container into the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) internal storage.

* You can safely modify your original container after calling [Mesh.SetVertices](/engine/6000.7/script-reference/unityengine/mesh/setvertices.md) without affecting the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) data.
* You can reuse the same source container to set data for multiple different [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) objects.
* The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) does not keep a reference to your original container (especially relevant for managed arrays and lists).

**Vertex Count:** Calling this method overwrites all existing vertex positions. The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) vertex count (see [Mesh.vertexCount](/engine/6000.7/script-reference/unityengine/mesh/vertexcount.md)) will be adjusted to match the number of elements in the `inVertices` container you provide. If you subsequently set other per-vertex data (like normals or UVs), ensure their count matches the new vertex count.

This method is often used as the underlying implementation for the [Mesh.vertices](/engine/6000.7/script-reference/unityengine/mesh/vertices.md) property setter. For frequent updates, consider calling [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md) first, which may improve performance by optimizing the underlying GPU buffer strategy.

```csharp
using UnityEngine;
using Unity.Collections;

// This script demonstrates how to create a simple quad mesh from scratch.
// Attach this script to an empty GameObject. It will create a Mesh and
// assign it to the MeshFilter, and add a default material to the MeshRenderer.
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SetVerticesFullExample : MonoBehaviour
{
    private Material m_Material;
    private Mesh m_Mesh;

    void Start()
    {
        // Create a new mesh object.
        m_Mesh = new Mesh();
        m_Mesh.name = "Procedural Quad";

        // Define the vertex and triangle data.
        var vertices = new NativeArray<Vector3>(4, Allocator.Temp);
        vertices[0] = new Vector3(-1, 0, -1);
        vertices[1] = new Vector3(-1, 0,  1);
        vertices[2] = new Vector3( 1, 0,  1);
        vertices[3] = new Vector3( 1, 0, -1);

        var triangles = new NativeArray<int>(6, Allocator.Temp);
        triangles[0] = 0; triangles[1] = 1; triangles[2] = 2; // First triangle
        triangles[3] = 0; triangles[4] = 2; triangles[5] = 3; // Second triangle

        // Populate the mesh with the data.
        m_Mesh.SetVertices(vertices);
        m_Mesh.SetIndices(triangles, MeshTopology.Triangles, 0);

        // Dispose of the NativeArrays now that the data is in the mesh.
        vertices.Dispose();
        triangles.Dispose();

        // Finalize the mesh state for rendering.
        m_Mesh.RecalculateNormals();
        m_Mesh.RecalculateBounds();

        // Get the required components and assign the fully constructed mesh and a material.
        var meshFilter = GetComponent<MeshFilter>();
        meshFilter.sharedMesh = m_Mesh;

        var renderer = GetComponent<MeshRenderer>();
        if (renderer.sharedMaterial == null)
        {
            m_Material  = new Material(Shader.Find("Unlit/Color")); 
            renderer.sharedMaterial = m_Material;
        }
    }

    void OnDestroy()
    {
        // Destroy the mesh when the component is destroyed to prevent memory leaks.
        if (m_Mesh != null)
            Destroy(m_Mesh);
        if (m_Material != null)
            Destroy(m_Material);
    }
}
```

Additional Resources: [Mesh.vertices](/engine/6000.7/script-reference/unityengine/mesh/vertices.md), [Mesh.vertexCount](/engine/6000.7/script-reference/unityengine/mesh/vertexcount.md), [Mesh.SetIndices](/engine/6000.7/script-reference/unityengine/mesh/setindices.md), [Mesh.SetNormals](/engine/6000.7/script-reference/unityengine/mesh/setnormals.md), [Mesh.SetUVs](/engine/6000.7/script-reference/unityengine/mesh/setuvs.md), [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md), [Mesh.RecalculateNormals](/engine/6000.7/script-reference/unityengine/mesh/recalculatenormals.md).

## SetVertices(Vector3\[], int, int, MeshUpdateFlags)

Sets the vertex positions for the entire [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) using data copied from a specific slice of a source container.

```csharp
public void SetVertices(Vector3[] inVertices, int start, int length, MeshUpdateFlags flags)
```

### Parameters

**** (\[Vector3\[]]\(/engine/6000.7/script-reference/unityengine/vector3)): The vertex positions to copy, which replaces existing [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) vertices and sets the new vertex count.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The zero-based index within `inVertices` where the slice of data to be copied begins.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The number of vertex positions to copy from `inVertices`, starting from the `start` index, which also becomes the new vertex count of the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md).**** (\[MeshUpdateFlags]\(/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags)): Optional flags to control behavior after setting the vertices, such as skipping automatic bounds recalculation (default is [MeshUpdateFlags.Default](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags/default.md)).

### Remarks

Use this method to assign a complete set of vertex positions to the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md), sourcing the data from a portion of a larger array, list, or `NativeArray`.

**Data Handling and Slicing:** This method behaves similarly to the full container overload, but only uses elements from the `inVertices` container starting at the `start` index and taking @@length@ number of elements. Unity copies this slice of position data into the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) internal storage.

* As with the full overload, you can safely modify the original source container after calling this method without affecting the `Mesh` data.
* The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) does not keep a reference to your original container.
* Ensure that `start` and `length` define a valid range within the bounds of the `inVertices` container.

**Mesh Update Flags:** The `flags` parameter allows you to control post-update operations. For example, using [MeshUpdateFlags.DontRecalculateBounds](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags/dontrecalculatebounds.md) can prevent the automatic (and potentially costly) recalculation of the mesh bounds if you intend to set them manually later or know they haven't changed significantly. See [MeshUpdateFlags](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags.md) for details.

For frequent updates using slices, consider calling [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md) first to potentially improve performance.

```csharp
using UnityEngine;
using Unity.Collections;
using UnityEngine.Rendering;

// This script demonstrates how to set mesh vertices using a slice of a larger data array.
// It creates two quads' worth of vertex data but only displays one at a time.
// Use the "Start Index Group" slider in the Inspector to switch between them.
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SetVerticesPartialExample : MonoBehaviour
{
    [Range(0,1)]
    public int startIndexGroup = 0;

    private Mesh m_Mesh;
    private NativeArray<Vector3> m_AllVertices;
    private int m_PreviousIndexGroup = -1;

    void Start()
    {
        m_Mesh = new Mesh();
        m_Mesh.name = "Partial Vertices Mesh";

        // Create a persistent NativeArray containing data for multiple potential quads.
        m_AllVertices = new NativeArray<Vector3>(8, Allocator.Persistent);

        // Quad 1 vertices (group 0)
        m_AllVertices[0] = new Vector3(-1, 0, -1);
        m_AllVertices[1] = new Vector3(-1, 0,  1);
        m_AllVertices[2] = new Vector3( 1, 0,  1);
        m_AllVertices[3] = new Vector3( 1, 0, -1);

        // Quad 2 vertices (group 1), offset on X axis
        m_AllVertices[4] = new Vector3( 2, 0, -1);
        m_AllVertices[5] = new Vector3( 2, 0,  1);
        m_AllVertices[6] = new Vector3( 4, 0,  1);
        m_AllVertices[7] = new Vector3( 4, 0, -1);

        var renderer = GetComponent<MeshRenderer>();
        renderer.material = new Material(Shader.Find("Unlit/Color"));

        var meshFilter = GetComponent<MeshFilter>();
        meshFilter.mesh = m_Mesh;
    }

    void Update()
    {
        if (m_PreviousIndexGroup == startIndexGroup)
            return;

        m_PreviousIndexGroup = startIndexGroup;

        // Set the mesh vertices using a slice of the full data array.
        int dataLength = 4;
        int startIndex = startIndexGroup * dataLength;

        // Copy the slice from m_AllVertices into the Mesh.
        m_Mesh.SetVertices(m_AllVertices, startIndex, dataLength, MeshUpdateFlags.DontRecalculateBounds);

        // Define the triangles for a single quad using a NativeArray.
        var triangles = new NativeArray<int>(6, Allocator.Temp);
        triangles[0] = 0; triangles[1] = 1; triangles[2] = 2;
        triangles[3] = 0; triangles[4] = 2; triangles[5] = 3;
        m_Mesh.SetIndices(triangles, MeshTopology.Triangles, 0);
        triangles.Dispose();

        // Recalculate bounds and normals manually.
        m_Mesh.RecalculateBounds();
        m_Mesh.RecalculateNormals();

        Debug.Log($"Mesh updated to show vertex group {startIndexGroup}.");
    }

    void OnDestroy()
    {
        // Dispose the persistent NativeArray and destroy the mesh to prevent memory leaks.
        if (m_AllVertices.IsCreated)
            m_AllVertices.Dispose();

        if (m_Mesh != null)
            Destroy(m_Mesh);
    }
}
```

Additional Resources: [Mesh.vertices](/engine/6000.7/script-reference/unityengine/mesh/vertices.md), [Mesh.vertexCount](/engine/6000.7/script-reference/unityengine/mesh/vertexcount.md), [Mesh.SetIndices](/engine/6000.7/script-reference/unityengine/mesh/setindices.md), [Mesh.SetNormals](/engine/6000.7/script-reference/unityengine/mesh/setnormals.md), [Mesh.SetUVs](/engine/6000.7/script-reference/unityengine/mesh/setuvs.md), [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md), [MeshUpdateFlags](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags.md), [Mesh.UploadMeshData](/engine/6000.7/script-reference/unityengine/mesh/uploadmeshdata.md).

## SetVertices\<T>(NativeArray\<T>)

Assigns a new vertex positions array.

```csharp
public void SetVertices<T>(NativeArray<T> inVertices) where T : struct
```

### Parameters

**** (\[NativeArray\<T>]\(/engine/6000.7/script-reference/unity/collections/nativearray1)): The vertex positions to copy, which replaces existing [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) vertices and sets the new vertex count.

### Remarks

Use this method to assign a complete set of vertex positions to the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md). This is a fundamental operation for defining or modifying the shape of a mesh procedurally.

**Data Handling:** When you provide a container, Unity copies the position data from your container into the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) internal storage.

* You can safely modify your original container after calling [Mesh.SetVertices](/engine/6000.7/script-reference/unityengine/mesh/setvertices.md) without affecting the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) data.
* You can reuse the same source container to set data for multiple different [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) objects.
* The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) does not keep a reference to your original container (especially relevant for managed arrays and lists).

**Vertex Count:** Calling this method overwrites all existing vertex positions. The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) vertex count (see [Mesh.vertexCount](/engine/6000.7/script-reference/unityengine/mesh/vertexcount.md)) will be adjusted to match the number of elements in the `inVertices` container you provide. If you subsequently set other per-vertex data (like normals or UVs), ensure their count matches the new vertex count.

This method is often used as the underlying implementation for the [Mesh.vertices](/engine/6000.7/script-reference/unityengine/mesh/vertices.md) property setter. For frequent updates, consider calling [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md) first, which may improve performance by optimizing the underlying GPU buffer strategy.

```csharp
using UnityEngine;
using Unity.Collections;

// This script demonstrates how to create a simple quad mesh from scratch.
// Attach this script to an empty GameObject. It will create a Mesh and
// assign it to the MeshFilter, and add a default material to the MeshRenderer.
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SetVerticesFullExample : MonoBehaviour
{
    private Material m_Material;
    private Mesh m_Mesh;

    void Start()
    {
        // Create a new mesh object.
        m_Mesh = new Mesh();
        m_Mesh.name = "Procedural Quad";

        // Define the vertex and triangle data.
        var vertices = new NativeArray<Vector3>(4, Allocator.Temp);
        vertices[0] = new Vector3(-1, 0, -1);
        vertices[1] = new Vector3(-1, 0,  1);
        vertices[2] = new Vector3( 1, 0,  1);
        vertices[3] = new Vector3( 1, 0, -1);

        var triangles = new NativeArray<int>(6, Allocator.Temp);
        triangles[0] = 0; triangles[1] = 1; triangles[2] = 2; // First triangle
        triangles[3] = 0; triangles[4] = 2; triangles[5] = 3; // Second triangle

        // Populate the mesh with the data.
        m_Mesh.SetVertices(vertices);
        m_Mesh.SetIndices(triangles, MeshTopology.Triangles, 0);

        // Dispose of the NativeArrays now that the data is in the mesh.
        vertices.Dispose();
        triangles.Dispose();

        // Finalize the mesh state for rendering.
        m_Mesh.RecalculateNormals();
        m_Mesh.RecalculateBounds();

        // Get the required components and assign the fully constructed mesh and a material.
        var meshFilter = GetComponent<MeshFilter>();
        meshFilter.sharedMesh = m_Mesh;

        var renderer = GetComponent<MeshRenderer>();
        if (renderer.sharedMaterial == null)
        {
            m_Material  = new Material(Shader.Find("Unlit/Color")); 
            renderer.sharedMaterial = m_Material;
        }
    }

    void OnDestroy()
    {
        // Destroy the mesh when the component is destroyed to prevent memory leaks.
        if (m_Mesh != null)
            Destroy(m_Mesh);
        if (m_Material != null)
            Destroy(m_Material);
    }
}
```

Additional Resources: [Mesh.vertices](/engine/6000.7/script-reference/unityengine/mesh/vertices.md), [Mesh.vertexCount](/engine/6000.7/script-reference/unityengine/mesh/vertexcount.md), [Mesh.SetIndices](/engine/6000.7/script-reference/unityengine/mesh/setindices.md), [Mesh.SetNormals](/engine/6000.7/script-reference/unityengine/mesh/setnormals.md), [Mesh.SetUVs](/engine/6000.7/script-reference/unityengine/mesh/setuvs.md), [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md), [Mesh.RecalculateNormals](/engine/6000.7/script-reference/unityengine/mesh/recalculatenormals.md).

## SetVertices\<T>(NativeArray\<T>, int, int, MeshUpdateFlags)

Sets the vertex positions for the entire [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) using data copied from a specific slice of a source container.

```csharp
public void SetVertices<T>(NativeArray<T> inVertices, int start, int length, MeshUpdateFlags flags) where T : struct
```

### Parameters

**** (\[NativeArray\<T>]\(/engine/6000.7/script-reference/unity/collections/nativearray1)): The vertex positions to copy, which replaces existing [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) vertices and sets the new vertex count.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The zero-based index within `inVertices` where the slice of data to be copied begins.**** (\[int]\(https\://learn.microsoft.com/dotnet/api/system.int32)): The number of vertex positions to copy from `inVertices`, starting from the `start` index, which also becomes the new vertex count of the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md).**** (\[MeshUpdateFlags]\(/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags)): Optional flags to control behavior after setting the vertices, such as skipping automatic bounds recalculation (default is [MeshUpdateFlags.Default](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags/default.md)).

### Remarks

Use this method to assign a complete set of vertex positions to the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md), sourcing the data from a portion of a larger array, list, or `NativeArray`.

**Data Handling and Slicing:** This method behaves similarly to the full container overload, but only uses elements from the `inVertices` container starting at the `start` index and taking @@length@ number of elements. Unity copies this slice of position data into the [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) internal storage.

* As with the full overload, you can safely modify the original source container after calling this method without affecting the `Mesh` data.
* The [Mesh](/engine/6000.7/script-reference/unityengine/mesh.md) does not keep a reference to your original container.
* Ensure that `start` and `length` define a valid range within the bounds of the `inVertices` container.

**Mesh Update Flags:** The `flags` parameter allows you to control post-update operations. For example, using [MeshUpdateFlags.DontRecalculateBounds](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags/dontrecalculatebounds.md) can prevent the automatic (and potentially costly) recalculation of the mesh bounds if you intend to set them manually later or know they haven't changed significantly. See [MeshUpdateFlags](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags.md) for details.

For frequent updates using slices, consider calling [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md) first to potentially improve performance.

```csharp
using UnityEngine;
using Unity.Collections;
using UnityEngine.Rendering;

// This script demonstrates how to set mesh vertices using a slice of a larger data array.
// It creates two quads' worth of vertex data but only displays one at a time.
// Use the "Start Index Group" slider in the Inspector to switch between them.
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SetVerticesPartialExample : MonoBehaviour
{
    [Range(0,1)]
    public int startIndexGroup = 0;

    private Mesh m_Mesh;
    private NativeArray<Vector3> m_AllVertices;
    private int m_PreviousIndexGroup = -1;

    void Start()
    {
        m_Mesh = new Mesh();
        m_Mesh.name = "Partial Vertices Mesh";

        // Create a persistent NativeArray containing data for multiple potential quads.
        m_AllVertices = new NativeArray<Vector3>(8, Allocator.Persistent);

        // Quad 1 vertices (group 0)
        m_AllVertices[0] = new Vector3(-1, 0, -1);
        m_AllVertices[1] = new Vector3(-1, 0,  1);
        m_AllVertices[2] = new Vector3( 1, 0,  1);
        m_AllVertices[3] = new Vector3( 1, 0, -1);

        // Quad 2 vertices (group 1), offset on X axis
        m_AllVertices[4] = new Vector3( 2, 0, -1);
        m_AllVertices[5] = new Vector3( 2, 0,  1);
        m_AllVertices[6] = new Vector3( 4, 0,  1);
        m_AllVertices[7] = new Vector3( 4, 0, -1);

        var renderer = GetComponent<MeshRenderer>();
        renderer.material = new Material(Shader.Find("Unlit/Color"));

        var meshFilter = GetComponent<MeshFilter>();
        meshFilter.mesh = m_Mesh;
    }

    void Update()
    {
        if (m_PreviousIndexGroup == startIndexGroup)
            return;

        m_PreviousIndexGroup = startIndexGroup;

        // Set the mesh vertices using a slice of the full data array.
        int dataLength = 4;
        int startIndex = startIndexGroup * dataLength;

        // Copy the slice from m_AllVertices into the Mesh.
        m_Mesh.SetVertices(m_AllVertices, startIndex, dataLength, MeshUpdateFlags.DontRecalculateBounds);

        // Define the triangles for a single quad using a NativeArray.
        var triangles = new NativeArray<int>(6, Allocator.Temp);
        triangles[0] = 0; triangles[1] = 1; triangles[2] = 2;
        triangles[3] = 0; triangles[4] = 2; triangles[5] = 3;
        m_Mesh.SetIndices(triangles, MeshTopology.Triangles, 0);
        triangles.Dispose();

        // Recalculate bounds and normals manually.
        m_Mesh.RecalculateBounds();
        m_Mesh.RecalculateNormals();

        Debug.Log($"Mesh updated to show vertex group {startIndexGroup}.");
    }

    void OnDestroy()
    {
        // Dispose the persistent NativeArray and destroy the mesh to prevent memory leaks.
        if (m_AllVertices.IsCreated)
            m_AllVertices.Dispose();

        if (m_Mesh != null)
            Destroy(m_Mesh);
    }
}
```

Additional Resources: [Mesh.vertices](/engine/6000.7/script-reference/unityengine/mesh/vertices.md), [Mesh.vertexCount](/engine/6000.7/script-reference/unityengine/mesh/vertexcount.md), [Mesh.SetIndices](/engine/6000.7/script-reference/unityengine/mesh/setindices.md), [Mesh.SetNormals](/engine/6000.7/script-reference/unityengine/mesh/setnormals.md), [Mesh.SetUVs](/engine/6000.7/script-reference/unityengine/mesh/setuvs.md), [Mesh.MarkDynamic](/engine/6000.7/script-reference/unityengine/mesh/markdynamic.md), [MeshUpdateFlags](/engine/6000.7/script-reference/unityengine/rendering/meshupdateflags.md), [Mesh.UploadMeshData](/engine/6000.7/script-reference/unityengine/mesh/uploadmeshdata.md).
