Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How can I improve my performance?

Discussion in 'Scripting' started by XukeLho, Mar 18, 2016.

  1. XukeLho

    XukeLho

    Joined:
    Dec 30, 2014
    Posts:
    199
    I'm trying to create, not exactly a game, but more of a level builder for my class project.

    When I click on a button, it gives me a 'Canvas' where I can start building my level. My big problem is the creating of this canvas. It is a grid (X x Z, with no Y value), where the user inputs the width and depth and the number of divisions per X and Z.
    So far so good, but the problem starts now. Users must be able to manipulate this grid, so the verteces and lines of this grid must be interactable gameobjects.

    These 2 things are mandatory for the project:
    1. The verteces of the grid must be spheres
    2. and the lines must be tubes, and the radial division of these tubes must be parameterizable. This must be done this way so that I can control the lines meshes in relation to the camera. For example, If the line is far away, it is not very round, its a prism. If it is at mid distance, its an extruded octagon (don't know the 3D name for it), and so on.

    The vertices (spheres) are the easy ones. They are a prefab with the required scripts attached and are instanciated as needed.
    The lines are a bit trickyer because they are manually created gameobjects, where I need to create the mesh by calculating the triangulations, UVs, etc etc. But also doable.

    My problem starts now. This grid must be created when the user inputs the required values and presses the create button. When creating a medium or large grid, this takes a veeeeery long time!
    In a 30x30 units, with 10x10 divisions, it takes about 30 secs to create this grid.
    If my math is correct, thats like 100 verteces (prefab spheres), and close to 200 lines (manually created gameobjects).

    I've tryed reducing the number of polygons, by forcing the lines to allways be prisms, just for testing purposes, but that only got me about 3 seconds faster. Wich leades the to the conclusion that it is not a GPU problem but a CPU one, due to the amount of objects.


    Any sugestions on how to improve this?
     
  2. deliriumz

    deliriumz

    Joined:
    Aug 22, 2012
    Posts:
    34
    instead the gameobjects in advance, and manipulate them at runtime by enabling / disabling and modifying the properties. The expensive part will be the instantiation. If you're instantiating a bunch of objects constantly, you're hammering the garbage collector. When starting the level builder, cache the instantiation of all the objects. This way, you have your up front load, but it should be relatively smooth at runtime.
     
  3. XukeLho

    XukeLho

    Joined:
    Dec 30, 2014
    Posts:
    199
    The objects aren't being instantiated all the time. They are only instantiated once, at the time of the grid creation, when the user presses the button and this is my one and only problem, the creation of the objects. I could try cache some 300 vertices, but not the lines. Don't know if it would work, because the vertices need to know wich lines are connecting to them.
     
  4. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    There don't necessarily have to be any gameobjects in the grid, if you handle mouse events manually. Tracking the coordinates that cursor is clicked on and doing actions based on it. From Input class you get cursor position, and having script with this
    Code (CSharp):
    1. void OnMouseDown() {
    2.   //Handle coords here
    3. }
    4.  
    in the grid object with a box collider, it should get you started. It can be tricky and much work ahead if you go this way.

    But if we get back to the original attempt, could you show some code maybe on what's happening when grid is created? Are the prefabs too complex?
     
  5. XukeLho

    XukeLho

    Joined:
    Dec 30, 2014
    Posts:
    199
    Handling things with OnMouseDown() may change frame-to-frame performance but won't change the time it takes to create the empty gameobject with the collider. I would still need to create over 300 objects and that is the slow part that I need to improve. The creating of the objects and not the handling.
     
  6. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    What objects? To click edge between tiles for example is just a matter of math. You don't even need to go through a for loop or anything, so this is super fast with no memory take. Some ideas:
    Code (CSharp):
    1. const tileSize = 1f; // unit size for 1 tile
    2.  
    3. void OnMouseDown() {
    4.   Vector2 cursor = Input...something..mouse.cursor.position?
    5.   Vector2 gridPos = new Vector2((int)cursor.x / tileSize, (int)cursor.y / tileSize);
    6.   Vector2 delta = cursor - gridPos * tileSize;
    7.   // Determine where click was
    8.   if (delta.x < tileSize * 0.1f) {
    9.     // Left side
    10.     if (delta.y < tileSize * 0.1f) {
    11.       // Top left corner
    12.    
    13.     } else if (delta.y > tileSize * 0.9f) {
    14.       // Bottom left corner
    15.      
    16.     } else {
    17.       // Left edge
    18.      
    19.     }
    20.   } else if (delta.x > tileSize * 0.9f) {
    21.     // Right side
    22.     if (delta.y < tileSize * 0.1f) {
    23.       // Top right corner
    24.    
    25.     } else if (delta.y > tileSize * 0.9f) {
    26.       // Bottom right corner
    27.      
    28.     } else {
    29.       // Right edge
    30.      
    31.     }
    32.   } else {
    33.     // Middle of tile
    34.    
    35.   }
    36. }
     
  7. XukeLho

    XukeLho

    Joined:
    Dec 30, 2014
    Posts:
    199
    the user has total control over the camera, so that wont work
     
  8. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    Then raytrace cursor position to 3D plane? You'll again get exactly the coordinates in the relative place of tile grid no matter which angle or position you look at it.
     
  9. XukeLho

    XukeLho

    Joined:
    Dec 30, 2014
    Posts:
    199
    if the user moves a vertex, it wil stop being regular grid. not to mention, the mose click would have to be in the exact center of the vertex, wich is very unlikely to happen. I need the verteces to have click areas, and in order to have click areas they need to be gameobjects, and i need alot of gameobjects, wich takes us back to the problem of making alot of them fast
     
  10. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    At least i tried :p The mathematical areas i mentioned are like these 9:
    tile.png
    And you can easily make the red areas bigger or smaller, just by changing the numbers. And the 1 code works for the entire grid at the same time, which is why i said it'd be fast.