Terrain refresh lag unity c# - How effectively refresh the terrain?

1k views Asked by At

In the game, players are able to chop down trees. I then instantiate a falling tree in it's spot.

I remove the tree from the terrain list and refresh the terrain like so:

        var treeInstancesToRemove = new List<TreeInstance>(terrain.treeInstances);
        treeInstancesToRemove.RemoveAt(closestTreeIndex);
        terrain.treeInstances = treeInstancesToRemove.ToArray();

        // I refresh the terrain so the collider gets removed...
        float[,] heights = terrain.GetHeights(0, 0, 0, 0);
        terrain.SetHeights(0, 0, heights);

The terrain is VERY LARGE... This means that whenever a tree is chopped the game freezes for a few seconds and then resumes (as it refreshes). Is there a faster or more effective way I could take a look at? Having a freeze after every tree you chop down is not quite ideal?

THANKS A LOT IN ADVANCE!

2

There are 2 answers

1
Benjamin James Drury On BEST ANSWER

The best thing I can suggest is having the world split into chunks that you can update separately. Either that, or have the collider update in a separate thread from the main one.

1
Willie Wight On
    float hmWidth = grav.currentTerrain.terrainData.heightmapWidth;
    float hmHeight = grav.currentTerrain.terrainData.heightmapHeight;
    // get the normalized position of this game object relative to the terrain
    Vector3 tempCoord = (transform.position - grav.currentTerrain.gameObject.transform.position);
    Vector3 coord;
    coord.x = tempCoord.x / grav.currentTerrain.terrainData.size.x;
    coord.y = tempCoord.y / grav.currentTerrain.terrainData.size.y;
    coord.z = tempCoord.z / grav.currentTerrain.terrainData.size.z;
    // get the position of the terrain heightmap where this game object is
    int posXInTerrain = (int)(coord.x * hmWidth);
    int posYInTerrain = (int)(coord.z * hmHeight);
    // we set an offset so that all the raising terrain is under this game object
    //int offset = size / 2;

    // get the heights of the terrain under this game object
    float[,] heights = grav.currentTerrain.terrainData.GetHeights(posXInTerrain, posYInTerrain, 1, 1);
    grav.currentTerrain.terrainData.SetHeights(posXInTerrain, posYInTerrain, heights);  //THIS CHANGES TERRAIN FOR GOOD