Skip to content

Instantly share code, notes, and snippets.

@quill18
Last active August 28, 2018 20:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quill18/9becf56f685e60109551e034385fd8f9 to your computer and use it in GitHub Desktop.
Save quill18/9becf56f685e60109551e034385fd8f9 to your computer and use it in GitHub Desktop.
// RaiseTerrain.cs -- a simple script that raises (or lowers) Unity's built in terrain to be level
// with a GameObject's collider(s).
//
// AUTHOR: Martin "quill18" Glaude -- quill18@quill18.com
// LICENSE: CC0
//
// The latest version will always be available at: https://gist.github.com/quill18/9becf56f685e60109551e034385fd8f9
//
using UnityEngine;
using System.Collections;
public class RaiseTerrain : MonoBehaviour
{
// Use this for initialization
void Start()
{
UpdateTerrain(); // NOTE: Start() may or may not be where you want this to happen.
}
public Terrain Terrain;
[ContextMenu("Update Terrain")] // In case you want to be able to update the terrain in the editor without running the game
public void UpdateTerrain()
{
if(Terrain == null)
{
Debug.LogError("Please link TheTerrain to the appropriate terrain object.");
return;
}
// Get all colliders on our object (this includes the current GameObject as well)
Collider[] cols = GetComponentsInChildren<Collider>();
if (cols.Length == 0)
{
Debug.LogError("No colliders on this object.");
return;
}
// We need to determine our total bounding box
Bounds bounds = new Bounds(cols[0].bounds.center, cols[0].bounds.size);
for (int i = 1; i < cols.Length; i++)
{
bounds.Encapsulate(cols[i].bounds);
}
// The "near/left" corner of our object's area.
Vector3 worldPos = bounds.min;
Vector3 terrainLocalPos = worldPos - Terrain.transform.position;
// Normalize the position into terrain "sample units"
int indexX = (int)(terrainLocalPos.x / Terrain.terrainData.heightmapScale.x);
int indexY = (int)(terrainLocalPos.z / Terrain.terrainData.heightmapScale.z);
float newHeight = terrainLocalPos.y / Terrain.terrainData.heightmapScale.y;
// The size of the area in number of samples
int areaX = Mathf.CeilToInt(Mathf.Ceil((bounds.max.x) / Terrain.terrainData.heightmapScale.x) - indexX) + 1;
int areaY = Mathf.CeilToInt(Mathf.Ceil((bounds.max.z) / Terrain.terrainData.heightmapScale.z) - indexY) + 1;
float[,] heights = Terrain.terrainData.GetHeights((int)indexX, (int)indexY, areaX, areaY);
for (int x = 0; x < areaX; x++)
{
for (int y = 0; y < areaY; y++)
{
heights[y, x] = newHeight; // Why does x and y have to be inverted here?
}
}
Terrain.terrainData.SetHeights((int)indexX, (int)indexY, heights);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment