using UnityEngine; namespace TT_TerrainTools { public static class TT_TerrainHelpers { public enum EDirection { TOP = 0, BOTTOM = 1, LEFT = 2, RIGHT = 3 } public static void FixBorders(Terrain p_terrainA, Terrain p_terrainB, EDirection p_borderA, EDirection p_borderB, float p_fade) { int heightmapResolution = p_terrainA.terrainData.heightmapResolution; if (p_terrainA.terrainData.heightmapResolution != heightmapResolution || p_terrainB.terrainData.heightmapResolution != heightmapResolution) { Debug.LogError("TT_Terrain9Patch: both TerrainData assets must have the same 'heightmapResolution'!"); return; } p_fade = Mathf.Clamp01(p_fade); bool flag = false; bool flag2 = false; float y = p_terrainA.transform.position.y; float y2 = p_terrainA.terrainData.size.y; float y3 = p_terrainB.transform.position.y; float y4 = p_terrainB.terrainData.size.y; float[,] directedHeights = GetDirectedHeights(p_terrainA.terrainData, p_borderA); float[,] directedHeights2 = GetDirectedHeights(p_terrainB.terrainData, p_borderB); for (int i = 0; i < heightmapResolution; i++) { float directedWorldHeight = GetDirectedWorldHeight(i, p_borderA, directedHeights, p_terrainA); float directedWorldHeight2 = GetDirectedWorldHeight(i, p_borderB, directedHeights2, p_terrainB); float num = directedWorldHeight * (1f - p_fade) + directedWorldHeight2 * p_fade; SetDirectedWorldHeight(num, i, p_borderA, directedHeights, y, y2); SetDirectedWorldHeight(num, i, p_borderB, directedHeights2, y3, y4); flag = flag || num != directedWorldHeight; flag2 = flag2 || num != directedWorldHeight2; } if (flag) { SetDirectedHeights(directedHeights, p_terrainA.terrainData, p_borderA); } if (flag2) { SetDirectedHeights(directedHeights2, p_terrainB.terrainData, p_borderB); } } private static float GetDirectedWorldHeight(int p_index, EDirection p_border, float[,] p_heights, Terrain p_terrain) { return p_terrain.transform.position.y + p_terrain.terrainData.size.y * GetDirectedLocalHeight(p_index, p_border, p_heights); } private static float GetDirectedLocalHeight(int p_index, EDirection p_border, float[,] p_heights) { switch (p_border) { case EDirection.LEFT: case EDirection.RIGHT: return p_heights[p_index, 0]; default: return p_heights[0, p_index]; } } private static void SetDirectedWorldHeight(float p_value, int p_index, EDirection p_border, float[,] p_heights, float p_terrainPosY, float p_terrainSizeY) { float p_value2 = (p_value - p_terrainPosY) / p_terrainSizeY; SetDirectedLocalHeight(p_value2, p_index, p_border, p_heights); } private static void SetDirectedLocalHeight(float p_value, int p_index, EDirection p_border, float[,] p_heights) { switch (p_border) { case EDirection.LEFT: case EDirection.RIGHT: p_heights[p_index, 0] = p_value; break; default: p_heights[0, p_index] = p_value; break; } } private static float[,] GetDirectedHeights(TerrainData p_terrainData, EDirection p_border) { int heightmapResolution = p_terrainData.heightmapResolution; switch (p_border) { case EDirection.RIGHT: return p_terrainData.GetHeights(heightmapResolution - 1, 0, 1, heightmapResolution); case EDirection.LEFT: return p_terrainData.GetHeights(0, 0, 1, heightmapResolution); case EDirection.BOTTOM: return p_terrainData.GetHeights(0, 0, heightmapResolution, 1); default: return p_terrainData.GetHeights(0, heightmapResolution - 1, heightmapResolution, 1); } } private static void SetDirectedHeights(float[,] p_heights, TerrainData p_terrainData, EDirection p_border) { int heightmapResolution = p_terrainData.heightmapResolution; switch (p_border) { case EDirection.RIGHT: p_terrainData.SetHeights(heightmapResolution - 1, 0, p_heights); break; case EDirection.LEFT: p_terrainData.SetHeights(0, 0, p_heights); break; case EDirection.BOTTOM: p_terrainData.SetHeights(0, 0, p_heights); break; default: p_terrainData.SetHeights(0, heightmapResolution - 1, p_heights); break; } } } }