using System.Collections.Generic; using UnityEngine; namespace Gaia { public class TerrainHelper : MonoBehaviour { [Range(1f, 5f)] [Tooltip("Number of smoothing interations to run. Can be run multiple times.")] public int m_smoothIterations = 1; private void Awake() { base.gameObject.SetActive(value: false); } public static void Flatten() { FlattenTerrain(Terrain.activeTerrains); } public static void FlattenTerrain(Terrain terrain) { int heightmapResolution = terrain.terrainData.heightmapResolution; int heightmapResolution2 = terrain.terrainData.heightmapResolution; float[,] heights = new float[heightmapResolution, heightmapResolution2]; terrain.terrainData.SetHeights(0, 0, heights); } public static void FlattenTerrain(Terrain[] terrains) { foreach (Terrain obj in terrains) { int heightmapResolution = obj.terrainData.heightmapResolution; int heightmapResolution2 = obj.terrainData.heightmapResolution; float[,] heights = new float[heightmapResolution, heightmapResolution2]; obj.terrainData.SetHeights(0, 0, heights); } } public static void Stitch() { StitchTerrains(Terrain.activeTerrains); } public static void StitchTerrains(Terrain[] terrains) { Terrain terrain = null; Terrain terrain2 = null; Terrain terrain3 = null; Terrain terrain4 = null; foreach (Terrain terrain5 in terrains) { terrain = null; terrain2 = null; terrain3 = null; terrain4 = null; foreach (Terrain terrain6 in terrains) { if (terrain6.transform.position.x == terrain5.transform.position.x) { if (terrain6.transform.position.z + terrain6.terrainData.size.z == terrain5.transform.position.z) { terrain4 = terrain6; } else if (terrain5.transform.position.z + terrain5.terrainData.size.z == terrain6.transform.position.z) { terrain3 = terrain6; } } else if (terrain6.transform.position.z == terrain5.transform.position.z) { if (terrain6.transform.position.x + terrain6.terrainData.size.z == terrain5.transform.position.z) { terrain2 = terrain6; } else if (terrain5.transform.position.x + terrain5.terrainData.size.x == terrain6.transform.position.x) { terrain = terrain6; } } } terrain5.SetNeighbors(terrain2, terrain4, terrain, terrain3); } } public void Smooth() { Smooth(m_smoothIterations); } public static void Smooth(int iterations) { UnityHeightMap unityHeightMap = new UnityHeightMap(Terrain.activeTerrain); unityHeightMap.Smooth(iterations); unityHeightMap.SaveToTerrain(Terrain.activeTerrain); } public static Vector3 GetActiveTerrainCenter(bool flushToGround = true) { Bounds bounds = default(Bounds); Terrain activeTerrain = GetActiveTerrain(); if (GetTerrainBounds(activeTerrain, ref bounds)) { if (flushToGround) { return new Vector3(bounds.center.x, activeTerrain.SampleHeight(bounds.center), bounds.center.z); } return bounds.center; } return Vector3.zero; } public static Terrain GetActiveTerrain() { Terrain activeTerrain = Terrain.activeTerrain; if (activeTerrain != null && activeTerrain.isActiveAndEnabled) { return activeTerrain; } for (int i = 0; i < Terrain.activeTerrains.Length; i++) { activeTerrain = Terrain.activeTerrains[i]; if (activeTerrain != null && activeTerrain.isActiveAndEnabled) { return activeTerrain; } } return null; } public static LayerMask GetActiveTerrainLayer() { LayerMask result = default(LayerMask); Terrain activeTerrain = GetActiveTerrain(); if (activeTerrain != null) { result.value = 1 << activeTerrain.gameObject.layer; return result; } result.value = 1 << LayerMask.NameToLayer("Default"); return result; } public static LayerMask GetActiveTerrainLayerAsInt() { LayerMask layerMask = GetActiveTerrainLayer().value; for (int i = 0; i < 32; i++) { if ((int)layerMask == 1 << i) { return i; } } return LayerMask.NameToLayer("Default"); } public static int GetActiveTerrainCount() { int num = 0; for (int i = 0; i < Terrain.activeTerrains.Length; i++) { Terrain terrain = Terrain.activeTerrains[i]; if (terrain != null && terrain.isActiveAndEnabled) { num++; } } return num; } public static Terrain GetTerrain(Vector3 locationWU) { Vector3 vector = default(Vector3); Vector3 vector2 = default(Vector3); Terrain activeTerrain = Terrain.activeTerrain; if (activeTerrain != null) { vector = activeTerrain.GetPosition(); vector2 = vector + activeTerrain.terrainData.size; if (locationWU.x >= vector.x && locationWU.x <= vector2.x && locationWU.z >= vector.z && locationWU.z <= vector2.z) { return activeTerrain; } } for (int i = 0; i < Terrain.activeTerrains.Length; i++) { activeTerrain = Terrain.activeTerrains[i]; vector = activeTerrain.GetPosition(); vector2 = vector + activeTerrain.terrainData.size; if (locationWU.x >= vector.x && locationWU.x <= vector2.x && locationWU.z >= vector.z && locationWU.z <= vector2.z) { return activeTerrain; } } return null; } public static bool GetTerrainBounds(Terrain terrain, ref Bounds bounds) { if (terrain == null) { return false; } bounds.center = terrain.transform.position; bounds.size = terrain.terrainData.size; bounds.center += bounds.extents; return true; } public static bool GetTerrainBounds(Vector3 locationWU, ref Bounds bounds) { Terrain terrain = GetTerrain(locationWU); if (terrain == null) { return false; } bounds.center = terrain.transform.position; bounds.size = terrain.terrainData.size; bounds.center += bounds.extents; return true; } public static Vector3 GetRandomPositionOnTerrain(Terrain terrain, Vector3 start, float radius) { Vector3 position = terrain.GetPosition(); Vector3 vector = position + terrain.terrainData.size; Vector3 vector2; do { vector2 = Random.insideUnitSphere * radius; vector2 = start + vector2; } while (!(vector2.x >= position.x) || !(vector2.x <= vector.x) || !(vector2.z >= position.z) || !(vector2.z <= vector.z)); vector2.y = terrain.SampleHeight(vector2); return vector2; } public static void ClearTrees() { List list = new List(); for (int i = 0; i < Terrain.activeTerrains.Length; i++) { Terrain obj = Terrain.activeTerrains[i]; obj.terrainData.treeInstances = list.ToArray(); obj.Flush(); } Spawner[] array = Object.FindObjectsOfType(); foreach (Spawner spawner in array) { spawner.SetUpSpawnerTypeFlags(); if (spawner.IsTreeSpawner()) { spawner.ResetSpawner(); } } } public static void ClearDetails() { for (int i = 0; i < Terrain.activeTerrains.Length; i++) { Terrain terrain = Terrain.activeTerrains[i]; int[,] details = new int[terrain.terrainData.detailWidth, terrain.terrainData.detailHeight]; for (int j = 0; j < terrain.terrainData.detailPrototypes.Length; j++) { terrain.terrainData.SetDetailLayer(0, 0, j, details); } terrain.Flush(); } Spawner[] array = Object.FindObjectsOfType(); foreach (Spawner spawner in array) { if (spawner.IsDetailSpawner()) { spawner.ResetSpawner(); } } } public static float GetRangeFromTerrain() { Terrain activeTerrain = GetActiveTerrain(); if (activeTerrain != null) { return Mathf.Max(activeTerrain.terrainData.size.x, activeTerrain.terrainData.size.z) / 2f; } return 0f; } } }