- Home /
Mesh SetVertices() vs vertices
Hi I noticed that the Mesh calss provide two ways of accessing the vertex and other structures. The SetVertices/UV and so on functions and the direct access to member array variables like .vertices, .uv and so on. All examples in the docs use the direct member variable arrays for modifying vertex data. What is the difference between these two, what should we prefer?
Thanks Dimi
Answer by Bunny83 · Jul 14, 2016 at 12:28 PM
There are several reasons for the new SetVertices / SetIndices / SetUVs / methods. First of all the old vertices property is not a variable. This fact has confused many users. It's a property. So actually there's a get method and a set method but the usage just looks like a variable.
What most did not understand is that the getter does not return a reference to an internall array but returns a copy. This is necessary since the actual vertex data is stored in the native C++ side of Unity. When you use the property (or the new GetXXX method) you always get a copy of the actual data so changing that copy has no effect on the actual data. To apply changes you had to assign that temp array back to the property in order to call the setter and pass the array back to Unity.
The new GetXXX and SetXXX makes it more clear about that since there are two seperate methods for getting the data and setting the data.
However the most important difference is if you want to change the data frequently you create a lot of garbage each time you convert a List to an array or when you use the getter of those properties. It's common to use Lists since they provide an easy and efficient way of adding / removing elements with minimal garbage production. You can keep your List instance and the GetXXX methods take in a List reference which they will fill. So once the List has reached the max amount you don't create any garbage when using GetXXX or SetXXX. So for frequent changes it's strongly recommended to use the GetXXX and SetXXX methods.
The next major point is the Get / Set method have now multiple overloads which allow you to pass in different types of vertex data. For example mesh.vertices
is an array of Vector3 Get and SetVertices can take in a List of Vector 2 / 3 / 4. So you finally can use the whole data channels. For vertices it seems irrelevant but it can be very important for UV. Most people use just 2d texture coordinates. However to get perspective correct texture mapping at very steep angles or non rectangles you would need 4d texcoords (uvpq):
See this image for a basic reference.
The shader does an automatic perspective correction of the texture coordinates in screen space based on the depth of each vertex. However since each triangle is rendered seperately it doesn't know how the mesh might continue in other triangles. At very steep angles or unusual shapes (not rectangular shapes) the seem between the triangles won't match. That's why there are UVPQ coordinates. For each vertex you can also define information on the actual shape of the mesh.
See this SO question.
So since there is now a SeUVs(List<Vector4>)
overload we finally can pass in 4d texture coordinates.
Finally SetIndices
allows you to specify a different mesh topology. mesh.triangles
only allows you to render triangles.
To sum up:
It's generally adviced to use the new GetXXX and SetXXX method if you do frequent changes to your mesh. They also allow you to use the full power of the GPU since you can now fill in almost any vertex data you like. So the new methods:
are more GC friendly
are more versatile
avoid confusion about the usage.
Thanks for the great explanation. I never had to pass in the q coordinate of a texture coordinate except for projective texturing. Thanks also for the perspective correct texture mapping explanation.
Answer by Eno-Khaon · Jul 14, 2016 at 09:54 AM
Based on a quick comparison of Unity's documentation for Mesh.SetVertices() and Mesh.vertices, SetVertices() reads in a List<Vector3> of values while Mesh.vertices utilizes a Vector3 Array.
// C#
Mesh m;
Vector3[] vertexArray;
System.Collections.Generic.List<Vector3> vertexList;
// ...
// These do the same thing using different data types
m.vertices = vertexArray;
m.SetVertices(vertexList);
In many circumstances, using the array might be ideal, since it already matches the data type of the vertices in the array, but if the assembly is better handled using a List, it could be more worthwhile to simply pass the List through instead.
Hi this is really strange since you can go from a List to an array very easily in C#. Why provide a redundant function. I suspect there is a reason for this new function methods regarding the C# garbage collector or some performance gain, avoid of copy etc.
Thanks
Your answer

Follow this Question
Related Questions
Modify mesh on load 1 Answer
How can I remove redundant vertices in custom mesh? 0 Answers
UV-ing a sphere procedurally 1 Answer
Connecting flatshaded vertices 0 Answers
how to remove vertices of a certain colour range from a mesh? 0 Answers