Jump to content

  • Log In with Google      Sign In   
  • Create Account


#Actualtharealjohn

Posted 12 July 2013 - 01:37 PM

Question: How can I offset some of the load of creating Terrain objects procedurally using a separate thread?

Background: I have been trying to get an "infinite" terrain system going using the Terrain objects in unity. I am procedurally creating the TerrainData objects, and then creating a Terrain object like this:

var t = Terrain.CreateTerrainGameObject(terrainData).GetComponent<Terrain>();

 

 

I need to keep track of my t objects so I know how many and which Terrains have been created. I am following a basic Tile grid, where each Terrain object is thought to be a Tile in the grid, located at coordinates like (0,0), (0,1), etc. The TerrainData object has all of its values and height mapping done using Perlin Noise. As I walk around I "cull" unneeded tiles of the Terrain that are "too far" away from the player. This results in a "rolling" set of 9 tiles surrounding the player, which is always at the center tile.

Here is where the question comes in. Creating the Perlin values for the TerrainData, along with the height map is very CPU intensive. I would like to do this on a separate thread, but because the TerrainData and Terrain objects are so closely linked, and they cannot be accessed on another thread, I am not sure how to architect my situation so I can use a separate thread for the Perlin and Height mapping bits.

An example of what I have (simplified):


List<Terrain> terrain = new List<Terrain>();
...

public Terrain CreateTerrain(int x, int y)
{
    // CPU intensive work
    CreateHeightMapValues(heightMap);

    // Fill in TerrainData values (I dont think this has to be done on the main thread)
    var td = new TerrainData();
    ....

    // Create the actual Terrain (Has to be done on the main thread)
    var t = Terrain.CreateTerrainGameObject(terrainData).GetComponent<Terrain>();

    // set position, etc.
    ... (misc work)

    return t;
}

I would like to wrap that CPU intensive work somehow in another thread, but because I need to return that Terrain object so I can add it to my List terrain, I cant just throw it off on another thread, because Ill need to wait anyway to create the actual Terrain object.

 

Can anyone suggest how to break it apart a little better so that I don't rely on the direct creation being linked to when I can add it to the list of terrain objects?

Note* That list is so I know how to destroy/create them when the player moves. It would also be nice to Destroy the Terrain object on a seperate thread so it doesnt lag the UI, but I dont think that is possible do to Unity's non-threadsafe environment.

 

I originally posted on Unity Answers, but thought this might be a good place too, as it is not 100% Unity specific, since it is mainly a architectural problem. Knowledge of Unity and its limitations is probably helpful though.

 

Also note that creating the threads and being able to invoke back on the main thread in Unity are not my problems, I have that code figured out. I just dont know how to use it effectively given the issues I mentioned above about 1 thing being needed for the other.


#1tharealjohn

Posted 12 July 2013 - 01:34 PM

Question: How can I offset some of the load of creating Terrain objects procedurally using a separate thread?

Background: I have been trying to get an "infinite" terrain system going using the Terrain objects in unity. I am procedurally creating the TerrainData objects, and then creating a Terrain object like this:

var t = Terrain.CreateTerrainGameObject(terrainData).GetComponent<Terrain>();

 

 

I need to keep track of my t objects so I know how many and which Terrains have been created. I am following a basic Tile grid, where each Terrain object is thought to be a Tile in the grid, located at coordinates like (0,0), (0,1), etc. The TerrainData object has all of its values and height mapping done using Perlin Noise. As I walk around I "cull" unneeded tiles of the Terrain that are "too far" away from the player. This results in a "rolling" set of 9 tiles surrounding the player, which is always at the center tile.

Here is where the question comes in. Creating the Perlin values for the TerrainData, along with the height map is very CPU intensive. I would like to do this on a separate thread, but because the TerrainData and Terrain objects are so closely linked, and they cannot be accessed on another thread, I am not sure how to architect my situation so I can use a separate thread for the Perlin and Height mapping bits.

An example of what I have (simplified):


List<Terrain> terrain = new List<Terrain>();
...

public Terrain CreateTerrain(int x, int y)
{
    // CPU intensive work
    CreateHeightMapValues(heightMap);

    // Fill in TerrainData values (I dont think this has to be done on the main thread)
    var td = new TerrainData();
    ....

    // Create the actual Terrain (Has to be done on the main thread)
    var t = Terrain.CreateTerrainGameObject(terrainData).GetComponent<Terrain>();

    // set position, etc.
    ... (misc work)

    return t;
}

I would like to wrap that CPU intensive work somehow in another thread, but because I need to return that Terrain object so I can add it to my List terrain, I cant just throw it off on another thread, because Ill need to wait anyway to create the actual Terrain object.

Can anyone suggest how to break it apart a little better so that I don't rely on the direct creation being linked to when I can add it to the list of terrain objects?

Note* That list is so I know how to destroy/create them when the player moves. It would also be nice to Destroy the Terrain object on a seperate thread so it doesnt lag the UI, but I dont think that is possible do to Unity's non-threadsafe environment.

I originally posted on Unity Answers, but thought this might be a good place too, as it is not 100% Unity specific, since it is mainly a architectural problem. Knowledge of Unity and its limitations is probably helpful though.


PARTNERS