Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Mesh.get_vertices gc collection very heavy!!!

Discussion in 'Scripting' started by dreamerflyer, Jun 20, 2015.

  1. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    move mesh verices in upate with unity 4.6.3, why so slowly??
     

    Attached Files:

    • psb.jpg
      psb.jpg
      File size:
      56.4 KB
      Views:
      941
    BenZed likes this.
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    GC happens automatically when the framework needs more memory. You are calling this method 2000 times per frame. And it's producing 45 Mb of garbage.

    Some context of what is happening in the scene, and what scripts you are using, would help.
     
  3. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Whenever you get the vertices from a mesh, Unity creates a new array. The moving is not the problem for you, it is the querying.
     
    Kiwasi likes this.
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You should create the array once and re-use it, instead of constantly getting the vertices.

    --Eric
     
    Kiwasi likes this.
  5. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    hi all,thanks for reply~.Below is my codes ,I don.t know What unity does...confused!
    Code (CSharp):
    1. Vector3 vertes[];
    2. void Update()
    3. {
    4. vertes=mesh.vertices;
    5. int i=0;
    6. while(i<vertes.Length)
    7. {
    8. vertes[i]+=Vector3.forward*Time.deltaTime;
    9. i++;
    10.  
    11. }
    12. mesh.vertices=verts;
    13. }
     
  6. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    How to fixed this?
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I already answered that...create the array once. You're creating it every Update.

    --Eric
     
  8. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    I just move the vertics which already exist only once....no create new array...
    you can try this:
    Code (CSharp):
    1. void Update()
    2. {
    3.  
    4. int i=0;
    5. while(i<mesh.vertices.Length)
    6. {
    7. mesh.vertices[i]+=Vector3.forward*Time.deltaTime;
    8. i++;
    9. }
    10.  
    11. }
     
  9. nafasso

    nafasso

    Joined:
    Dec 3, 2013
    Posts:
    22
    Code (CSharp):
    1. vertes=mesh.vertices;
    This line is written in your update function. Just put it in the start function instead and make the transformation only in the update.
     
  10. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    but how can move vertices in update,if not use "mesh.vertices+=Vector3.forward*Time.deltaTime;"
    if use mesh.vertices then create gc collection,this is the point.
     
  11. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    As mentioned, you need an array that you initialize e.g. in Start.
    Code (csharp):
    1. private Vector3[] vertices;
    2.  
    3. private void Start () {
    4.   vertices = mesh.vertices;
    5. }
    Your update will look as follows:
    Code (csharp):
    1. private void Update () {
    2.   int i = 0;
    3.   while (i < vertices.Length) {
    4.     vertices[i] += Vector3.forward * Time.deltaTime;
    5.     i++;
    6.   }
    7.  
    8.  mesh.vertices = vertices;
    9. }

    For the future it would make sense if you could post the code earlier. This makes it a lot easier to help. One of the issues is this:
    Code (csharp):
    1. while(i<mesh.vertices.Length)
    You just want the number of vertices, but what you get is the actual array each time and then it checks how many elements are in it. When you check the API, you will see that you can avoid that by using mesh.vertexCount. However, if you are using the solution as described earlier, this is not needed.
     
    Kiwasi likes this.
  12. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Normally this code wouldn't cause real issues. A reference is pretty light weight, and you can often throw them away without bothering he GC to much.

    But this is a special case.

    Every time you call Mesh.verticies it copies into a new array. So the entire array gets GC'd every frame. This is expensive.

    This behaviour is documented, and there are good performance reasons for it. But it is different from how arrays normally behave, so be wary.
     
  13. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    OK,thanks all! Got it!