Files
2026-03-04 10:03:45 +08:00

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;
}
}
}