Last active
August 28, 2018 20:49
-
-
Save quill18/9becf56f685e60109551e034385fd8f9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 -- [email protected] | |
// 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