292 lines
7.6 KiB
C#
292 lines
7.6 KiB
C#
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<TreeInstance> list = new List<TreeInstance>();
|
|
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<Spawner>();
|
|
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<Spawner>();
|
|
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;
|
|
}
|
|
}
|
|
}
|