How do I use Terrain.SetNeighbors() to remove level of detail seams between multiple terrains?

Please help explain how this method works I am Stumped

Basically, this command links the LOD (Level Of Detail) between adjacent terrain pieces, so that there are no level-of-detail seams.

To use it, first of all you need to make sure the heightmaps for your adjoining terrains exactly match along the edges, because SetNeighbors itself won't do this for you. If your heightmaps don't join seamlessly, you'll have seams whether you use SetNeighbors or not.

Assuming your heightmaps match exactly, you then need to specify for each terrain, which terrains join to the "left", "right", "top", and "bottom" - this is referring to directions as viewed from unity's "top view". IE: to the -X (left), +X (right), +Z (top) and -Z (bottom).

For example, if you have 9 terrains laid out like this:




the centre terrain (E) has 4 neighbours - top, left, bottom & right:


To specify these neighbours to the terrain engine, you would need a script placed on the terrain E object, with references to terrains B, D, H & F, something like this:

var terrainB : Terrain;
var terrainD : Terrain;
var terrainH : Terrain;
var terrainF : Terrain;

function Start() {
    var thisTerrain : Terrain = GetComponent(Terrain);
    thisTerrain.SetNeighbors( terrainD, terrainB, terrainF, terrainH);

To use this, you'd place the script on your terrain object, then drag references to the other neighbouring terrains into the four variables.

This would set up the "outgoing" neighbor references for terrain E, but in order to work properly, its neighbours must have reciprocal references pointing back to this terrain, so the neighbour links are 2-way.

While we could write another script, it's a little impractical to refer to each terrain by letter, and we don't want to write a separate script for each terrain piece. Better to use a more generic script which you could use on every terrain object. So we can make it more generic like this:

var terrainLeft : Terrain;
var terrainTop : Terrain;
var terrainRight : Terrain;
var terrainBottom : Terrain;

function Start() {
    var thisTerrain : Terrain = GetComponent(Terrain);
    thisTerrain.SetNeighbors( terrainLeft, terrainTop, terrainRight, terrainBottom);

Now you have a script which you can place on every terrain object. You simply need to assign all the links manually. For terrains which don't have a neighbour in a certain direction, just leave the variable empty - for example, terrain "A" above would only have links for "Bottom" and "Right".

Even this, in my opinion, seems like a lot of hard work (the manual assignment of all the links) and possibly prone to error if required for a large number of linked terrains, so if I were going to be doing this, I would be tempted to perhaps use a raycast in the Start function to automatically detect and assign the terrain neighbours.

To implement this, perhaps you could cast a ray downwards, in a position which would theoretically lie in the centre of a terrain's neighbour (if one exists there). Any raycasts which hit would be used to assign the neighbour in that direction. I'll leave the actual scripting for that as an excercise for whomever feels up to the challenge! :)

What i would be asking my self then would you know witch terrain is top/right etc within the editor window before assigning the script to each terrain 2.would the name of the terrain you give within the project view effect the function of the script or would the script still see it as a terrain 3.or should i name each terrain in project view according to the script like this

A-Terrain (A) B-Terrain (B) C-Terrain (C) : : : D-Terrain (D) E-Terrain (E) F-Terrain (F) : : : G-Terrain (G) H-Terrain (H) I-Terrain (I)

A=Right B =Bottom D B=Bottom E = Left A =Right C

And so on

Any help would be great

er gothic...what?

i think Duck answered it..its pretty straight forward. The key to it is naming.

Do the neighbors need to be updated per frame or some additional function calls need to be made beyond the cross linked terrain.setneighbors? I am fairly sure I have followed the above and still have cracks between my terrain tiles.

So… the names of the terrains must be “Terrain” alltogehter?