Search Unity

Terrain vertice information ?

Discussion in 'Scripting' started by userno101, Mar 11, 2010.

  1. userno101

    userno101

    Joined:
    Oct 4, 2009
    Posts:
    120
    I am interested in how they can get the field of vertices ( with position information about each vertice ,normals and materials ) from terrain ?
    Is there in Unity and terrain info function that returns all position, normals and material info ( name of material assigned to vertice ) of terrain vertices ?
    I wish collect all of them in to array.
    A need the same to create detail map from my terrain and then I assign some AI alghoritam ( probably A star path finding ) for search terrain .
    Thanks
     
    arunkumar_pk likes this.
  2. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    657
    There isn't any inbuild methods of getting vertices out as actual vertex data, but you can calculate the stuff by hand.
    (disclaimer: none of this is tested, it may have syntax errors, or other mistakes. It's just to give some ideas!)

    Vertex positions:

    Code (csharp):
    1. TerrainData myTerrainData = whateverTerrain.terrainData;
    2. float[,] allHeights = myTerrainData.GetHeights(0,0,myTerrainData.heightmapResolution,myTerrainData.heightmapResolution);
    3.  
    You can then use the Vector3 property "Size" to calculate the physical position of all the vertices.

    Normals:

    Code (csharp):
    1. TerrainData myTerrainData = whateverTerrain.terrainData;
    2.  
    3. Vector3 terrainNormals = myTerrainData.GetInterpolatedNormal(x,y);
    I have never used it myself, and have no idea if it wants heightmap coordinates (0 - heightmap resolution) or actual world coordinates (I would ges it to be heightmap coordinates), but you can try it out.

    As for you last thing, the texture (I guess you are looking for the texture at a specific spot, as a terrain object can't use multiple materials) can be found by looking into the alphamaps of the terrainData.

    Texture at coordinate:

    Code (csharp):
    1. Vector3 myLocationOnTerrain = myTransform.position - whateverTerrain.gameObect.transform.position;
    2. TerrainData myTerrainData = whateverTerrain.terrainData;
    3.  
    4. float[,,] terrainAlphamaps = myTerrainData.GetAlphamaps(0,0,myTerrainData.alphamapResolution,myTerrainData.alphamapResolution);
    5.  
    6. float[] retrievedTextureIntensities = new float[terrainAlphamaps.GetLength(2)];
    7.  
    8. Vector2 currentLocationOnAlphamap = new Vector2((myTerrainData.alphamapResolution/myTerrainData.Size.x)* myLocationOnTerrain.x,(myTerrainData.alphamapResolution/myTerrainData.Size.z)* myLocationOnTerrain.z);
    9.  
    10. for (int splatCount = 0; splatCount < terrainAlphamaps.GetLength(2); splatCount++) {
    11.  
    12.    retrievedTextureIntensities[splatCount] = terrainAlphamaps[currentLocationOnAlphamap.x,myTerrainData.alphamapResolution-currentLocationOnAlphamap.y,splatCount];
    13.  
    14. Debug.Log("Texture intensity for index " + splatCount + " : " + retrievedTextureIntensities[splatCount]);
    15.  
    16. }
    You can then use the index plus the intensity to look up in the terrainData.splatPrototypes[indexNumber] to see which Texture 2D that indes is.
    The alphamap coordinates are topdown, left right, which is why I'm reversing my z position coordinate.

    Hope it helps :)
     
    florianhanke likes this.
  3. userno101

    userno101

    Joined:
    Oct 4, 2009
    Posts:
    120
    Thanks a lot, this is very helpful . I will test it and try implement it in this weekend.