// src*: https://gist.github.com/andrew-raphael-lukasik/d2903247b3f9c94e6faa9c042d9f0460/
#if UNITY_EDITOR
[UnityEditor.MenuItem( "Tools/Fix All Terrain Seams" )]
static void FixAllSeams () { FixTerrains( Object.FindObjectsOfType<Terrain>() ); }
#endif
static void FixTerrains ( Terrain[] terrains )
{
foreach( var terrain in terrains ) FixTerrainsTopBottom( terrain );//Z axis pass
foreach( var terrain in terrains ) FixTerrainsLeftRight( terrain );//X axis pass
//note: passes are separated by axis to evade undesired complexities at corners
// (when corner shares more than one neighbor).
}
static void FixTerrainsTopBottom ( Terrain terrain )
{
#if UNITY_EDITOR
if( UnityEditor.EditorApplication.isPlaying==false ) UnityEditor.Undo.RegisterCompleteObjectUndo( terrain.terrainData , "Fix Seams" );
#endif
int length = terrain.terrainData.heightmapResolution;
int last = length-1;
Terrain TOP = terrain.topNeighbor;
Terrain BOTTOM = terrain.bottomNeighbor;
float[,] heights = terrain.terrainData.GetHeights( 0 , 0 , length , length );
int numSteps = length / 20;
if( TOP!=null )
{
float[,] topHeights = TOP.terrainData.GetHeights( 0 , 0 , length , length );
for( int x=0 ; x<length ; x++ )
{
float me = heights[ last , x ];
float other = topHeights[ 0 , x ];
if( me >= other ) { continue; }
float height = other;
for( int step=0 ; step<numSteps ; step++ )
{
//recursive lerp function:
height = Mathf.Lerp(
height ,
heights[ last-step , x ] ,
(float)step / (float)numSteps
);
heights[ last-step , x ] = height;
}
}
}
if( BOTTOM!=null )
{
float[,] bottomHeights = BOTTOM.terrainData.GetHeights( 0 , 0 , length , length );
for( int x=0 ; x<length ; x++ )
{
float me = heights[ 0 , x ];
float other = bottomHeights[ last , x ];
if( me >= other ) { continue; }
float height = other;
for( int step=0 ; step<numSteps ; step++ )
{
//recursive lerp function:
height = Mathf.Lerp(
height ,
heights[ step , x ] ,
(float)step / (float)numSteps
);
heights[ step , x ] = height;
}
}
}
terrain.terrainData.SetHeights( 0 , 0 , heights );
}
static void FixTerrainsLeftRight ( Terrain terrain )
{
#if UNITY_EDITOR
if( UnityEditor.EditorApplication.isPlaying==false ) UnityEditor.Undo.RegisterCompleteObjectUndo( terrain.terrainData , "Fix Seams" );
#endif
int length = terrain.terrainData.heightmapResolution;
int last = length-1;
Terrain RIGHT = terrain.rightNeighbor;
Terrain LEFT = terrain.leftNeighbor;
float[,] heights = terrain.terrainData.GetHeights( 0 , 0 , length , length );
int numSteps = length / 20;
if( RIGHT!=null )
{
float[,] rightHeights = RIGHT.terrainData.GetHeights( 0 , 0 , length , length );
for( int y=0 ; y<length ; y++ )
{
float me = heights[ y , last ];
float other = rightHeights[ y , 0 ];
if( me >= other ) { continue; }
float height = other;
for( int step=0 ; step<numSteps ; step++ )
{
//recursive lerp function:
height = Mathf.Lerp(
height ,
heights[ y , last-step ] ,
(float)step / (float)numSteps
);
heights[ y , last-step ] = height;
}
}
}
if( LEFT!=null )
{
float[,] leftHeights = LEFT.terrainData.GetHeights( 0 , 0 , length , length );
for( int y=0 ; y<length ; y++ )
{
float me = heights[ y , 0 ];
float other = leftHeights[ y , last ];
if( me >= other ) { continue; }
float height = other;
for( int step=0 ; step<numSteps ; step++ )
{
//recursive lerp function:
height = Mathf.Lerp(
height ,
heights[ y , step ] ,
(float)step / (float)numSteps
);
heights[ y , step ] = height;
}
}
}
terrain.terrainData.SetHeights( 0 , 0 , heights );
}
Last active
December 28, 2022 23:30
-
-
Save andrew-raphael-lukasik/d2903247b3f9c94e6faa9c042d9f0460 to your computer and use it in GitHub Desktop.
UnityEngine, Fix Terrain Seams
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment