オブジェクトをTerrain(地形)に転写

なんか試したら一瞬で出来たので。

コースのようなペラっとしたオブジェクトを選択してメニューを選ぶと、その部分の地形がそのオブジェクトに吸い付くように整地される。勿論、それまでの地形はキープ。

以下をEditor/フォルダにぶち込み。

//--------------------------------------------------------------------------------
// - ObjectToTerrain -
//--------------------------------------------------------------------------------
//
//	オブジェクトをTerrainに転写
//	元のTerrainはキープ
//
//--------------------------------------------------------------------------------

using UnityEngine;
using UnityEditor;
 
//--------------------------------------------------------------------------------
public class Object2Terrain : EditorWindow
{
	//----------------------------------------------------------------------------
	[MenuItem ("Edit/Export/Object to Terrain")]
	static void DoObject2Terrain()
	{
		BeginTransfer();
	}

	//----------------------------------------------------------------------------
	static void BeginTransfer ()
	{	
		if ( !Selection.activeGameObject ) {
			Debug.Log( "[Object2Terrain] No object is selected. " ); return;
		}

		TerrainData terrain_data = Terrain.activeTerrain.terrainData;
		Undo.RecordObject( Terrain.activeTerrain, "Object to Terrain" );
 
		GameObject	 target = Selection.activeGameObject;
		MeshCollider target_col = target.GetComponent<MeshCollider>();
		if ( !target_col ) {
			Debug.Log( "[Object2Terrain] No collider is detected in selection." ); return;
		}
		Bounds targetbounds = target_col.bounds;
		Bounds bounds = Terrain.activeTerrain.collider.bounds;
		
		// Do raycasting samples over the object to see what terrain heights should be
		float		cTerrainY		= Terrain.activeTerrain.GetPosition().y;
		int			cHMWidth		= terrain_data.heightmapWidth;
		int			cHMHeight		= terrain_data.heightmapHeight;
		float		cTerrainHeight	= terrain_data.size.y;

		float[,]	heightmap		= new float[ cHMWidth, cHMHeight ];	
		float[,]	originmap		= terrain_data.GetHeights( 0, 0, cHMWidth, cHMHeight );
		Vector3		ray_origin		= new Vector3( bounds.min.x, targetbounds.max.y * 2, bounds.min.z );
		Ray			ray				= new Ray( ray_origin, Vector3.down );
		RaycastHit	hit				= new RaycastHit();
		float		cRayDistance	= targetbounds.size.y * 4;
		Vector2		cNextDiv		= new Vector2( bounds.size.x / cHMHeight , bounds.size.z / cHMWidth );

		for (int i = 0; i < cHMWidth; i++)
		{
			for (int j = 0; j < cHMHeight; j++)
			{
				bool result = target_col.Raycast( ray, out hit, cRayDistance );
				if ( result ) {
					heightmap[i, j] = ( hit.point.y - cTerrainY ) / cTerrainHeight;
				} else {
					heightmap[i, j] = originmap[i, j];
				}
		   		ray_origin.x += cNextDiv.x;
		   		ray.origin = ray_origin;
			}
			ray_origin.z += cNextDiv.y;
	  		ray_origin.x = bounds.min.x;
	  		ray.origin = ray_origin;
		}

		terrain_data.SetHeights( 0, 0, heightmap );
	}
 
}

メッシュコライダをオブジェクトとTerrainにつけるのをお忘れなく。