コースのようなペラっとしたオブジェクトを選択してメニューを選ぶと、その部分の地形がそのオブジェクトに吸い付くように整地される。勿論、それまでの地形はキープ。
以下を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につけるのをお忘れなく。