Search Unity

Multithreading problems

Discussion in 'Scripting' started by AnomalusUndrdog, Apr 5, 2010.

  1. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,553
    I have code wherein I have this one function where I create a big mesh, adding 6,400 vertices, which is really lagging the program. But once its done, the program runs smoothly, so I thought of putting it in a separate thread.

    Here's the code:
    Code (csharp):
    1.  
    2. function Start()
    3. {
    4.     var createThread = new System.Threading.Thread( new System.Threading.ThreadStart(CreateFogOfWarMesh) );
    5.     createThread.Start();
    6. }
    7.  
    CreateFogOfWarMesh is the function in question.
    Code (csharp):
    1.  
    2. function CreateFogOfWarMesh()
    3. {
    4.     gameObject.AddComponent("MeshFilter");
    5.     gameObject.AddComponent("MeshRenderer");
    6.     gameObject.AddComponent("MeshCollider");
    7.  
    8.     mesh = GetComponent(MeshFilter).mesh;
    9.  
    10.     mesh.Clear();
    11.  
    12.     // vertices ---------------------------------------------------------------------------------
    13.     var verts = new Array();
    14.  
    15.     var pos = transform.position;
    16.     //var locZ = transform.position.z;
    17.  
    18.     for (var y = 0; y < yLength; ++y)
    19.     {
    20.         for (var x = 0; x < xLength; ++x)
    21.         {
    22.             verts.Push( AddVert(pos,(x*gridSize),(y*gridSize)) );
    23.         }
    24.     }
    25.     mesh.vertices = verts.ToBuiltin(Vector3);
    26.  
    27.     // uv's ----------------------------------------------------------------------------------------
    28.     var uvs = new  Vector2[verts.length];
    29.  
    30.     for (var i=0;i<uvs.Length;i++) {
    31.         uvs[i] = Vector2(verts[i].x, verts[i].z);
    32.     }
    33.     mesh.uv = uvs;
    34.  
    35.     // triangles ---------------------------------------------------------------------------------
    36.     var tris = new Array();
    37.     //var trilen = (mesh.vertices.length-2)/2;
    38.  
    39.     for (y = 0; y < yLength-1; ++y)
    40.     {
    41.         for (x = 0; x < xLength-1; ++x)
    42.         {
    43.             var vertHere = x+(y*xLength);
    44.             var vertAbove = x+((y+1)*xLength);
    45.             tris.Push(vertHere);
    46.             tris.Push(vertAbove);
    47.             tris.Push(vertAbove+1);
    48.  
    49.             tris.Push(vertHere);
    50.             tris.Push(vertAbove+1);
    51.             tris.Push(vertHere+1);
    52.             //Debug.Log(x + "," + y + ": " +
    53.             //  vertHere + "," + vertAbove + "," + (vertAbove+1) + " " +
    54.             //  vertHere + "," + (vertAbove+1) + "," + (vertHere+1));
    55.         }
    56.     }
    57.     mesh.triangles = tris.ToBuiltin(int);
    58.     mesh.RecalculateNormals();
    59.     mesh.RecalculateBounds();
    60.  
    61.     // vertex colors ------------------------------------------------------------------------------
    62.     var vertices = mesh.vertices;
    63.     colors = new Color[vertices.Length];
    64.  
    65.     for (i=0;i<vertices.Length;i++)
    66.     {
    67.         colors[i] = Color(0,0,0,targetAlpha);
    68.     }
    69.     mesh.colors = colors;
    70.  
    71.  
    72.     renderer.castShadows = false;
    73.     renderer.receiveShadows = false;
    74.     renderer.material = newMaterial;
    75.    
    76.     var meshCollider : MeshCollider = GetComponent(MeshCollider);
    77.     meshCollider.sharedMesh = mesh;
    78.     creationDone = true;
    79. }
    80.  
    The only problem is its spewing out lots of cryptic error messages upon starting, and there's a chance Unity will hang and I have to forcefully end its process.

    Any help is appreciated.
     

    Attached Files:

  2. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,553
    Ok, moving the gameObject.AddComponent function outside the thread lessened the amount of errors.

    Code (csharp):
    1.  
    2. function Start()
    3. {
    4.     gameObject.AddComponent("MeshFilter");
    5.     gameObject.AddComponent("MeshRenderer");
    6.     gameObject.AddComponent("MeshCollider");
    7.  
    8.     var createThread = new System.Threading.Thread( CreateFogOfWarMesh );
    9.     createThread.Start();
    10.     //CreateFogOfWarMesh();
    11. }
    12.  
    Weird thing is, I'm still getting a noticeable lag in my program even though its threaded already.
     

    Attached Files:

  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    you can not access any UnityEngine classes and functionality from within distinct threads.
    you can only work with the threadsafe System classes
     
  4. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,553
    I see, I guess that's too bad I can't stop my game from lagging upon initialization
     
  5. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Right you can't, thats why you normally do it as part of the loading after the actual scene is loaded. you just keep the loading screen there and do the initialization behind it for example.


    In this case though there would be ways to utilize threading as array etc are valid classes.
    so you can prepare these data.

    Question though is how much faster it would be if you stopped the dynamic expansion approach caused by Push.
     
  6. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,553
    The loading screen will become unresponsive though, I was hoping to multi-thread it so at least the loading screen can animate its progress bar without hiccups.

    The lag isn't coming from the arrays. Its when the actual mesh is created. When I removed the code that creates the mesh but left the code for the arrays, there was no lag.