- Home /
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
Answer by duck · May 22, 2010 at 10:52 AM
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:
A B C
D E F
G H I
the centre terrain (E) has 4 neighbours - top, left, bottom & right:
A B C
|
D-E-F
|
G H I
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! :)
Does the script have to be put on the terrain? Or could it be put on another object?
And how do I know it works? Is there a visual result from using setneighbors?
Answer by Elowan · Oct 21, 2014 at 01:16 PM
So... the names of the terrains must be "Terrain" alltogehter?
Cheers!
Answer by GothikaGirl · Mar 25, 2011 at 06:13 PM
What i would be asking my self then 1.how 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
Answer by Gambit 3 · Mar 25, 2011 at 06:31 PM
er gothic...what?
i think Duck answered it..its pretty straight forward. The key to it is naming.
Answer by mullencm · Jul 12, 2012 at 04:49 AM
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.
Your answer
![](https://koobas.hobune.stream/wayback/20220613014626im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
stitch spheriphied terrain-like (6) planes (removing gaps from edges) 6 Answers
I've stitched my terrains at runtime, but have a wild vertex not playing ball! Any suggestions? 0 Answers
Trying to tile terrain, encountering strange axis flipping 0 Answers
Custom terrain textures,seeing seams,how do I fix this? 2 Answers