-Auteur: Le geek
-Description : Ce petit script en C# permet de déformer un terrain à partir d'informations contenues dans une heightmap, même au format jpeg, png,... N'importe quelle texture préalablement importée peut faire l'affaire. Après quelques tests, 8 bits d'information suffisent, même si à l'avenir, je compte augmenter la résolution verticale.
-Utilisation : Il vous suffit d'avoir ce script dans votre projet. Vous pouvez le trouver dans Window -> Terrain tool
Un éditeur s'ouvre, et vous pouvez choisir le terrain à déformer, la texture à utiliser, ainsi que le facteur d'échelle qui vous permet de régler l'intensité de la déformation. Vous pouvez aussi remettre le terrain à plat en cliquant sur Reset (définitif)
Note importante: Lors de l'import de la texture, choisissez "Advanced", et "Read/Write Enabled".
-Script :
Code : Tout sélectionner
using UnityEngine;
using UnityEditor;
using System.Collections;
public class TerrainHeightMaps : EditorWindow
{
Terrain terrain=null;
Texture2D sourcetexture=null;
float factor=1f;
// Use this for initialization
void Start ()
{
}
[MenuItem("Window/Terrain tool")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(TerrainHeightMaps));
}
// Update is called once per frame
void OnGUI ()
{
terrain=EditorGUILayout.ObjectField(terrain,typeof(Terrain),true) as Terrain;
sourcetexture=EditorGUILayout.ObjectField(sourcetexture,typeof(Texture2D),true) as Texture2D;
factor=EditorGUILayout.FloatField("Scale Factor",factor);
if(GUILayout.Button("Deform terrain!"))
{
if(terrain && sourcetexture)
{
DeformTerrain(sourcetexture,terrain.terrainData);
}
else
{
if(!terrain && !sourcetexture)
EditorUtility.DisplayDialog("Error!","Please select terrain and texture","OK");
if(!sourcetexture && terrain)
EditorUtility.DisplayDialog("Error!","Please select a texture","OK");
if(!terrain && sourcetexture)
EditorUtility.DisplayDialog("Error!","Please select a terrain","OK");
}
}
if(GUILayout.Button("Reset"))
{
if(terrain)
{
string message="Are you sure you want to reset terrain height?\nYou cannot undo this action";
if(EditorUtility.DisplayDialog("Warning!",message,"Yes","No"))
{
ResetTerrainHeight(terrain.terrainData);
}
}
else
{
EditorUtility.DisplayDialog("Error!","Please select terrain first","OK");
}
}
}
public void ResetTerrainHeight(TerrainData dat)
{
int w = dat.heightmapWidth;
int h = dat.heightmapHeight;
float[,] heights = dat.GetHeights(0,0,w,h);//Get the whole heightmap as a matrix of floats
for(int i=0;i<w;i++)
{
for(int j=0;j<h;j++)
{
heights[i,j]=0f;
}
}
dat.SetHeights(0,0,heights);
}
public void DeformTerrain(Texture2D map,TerrainData dat)
{
try
{
Color[] mapColors = map.GetPixels();
int w = dat.heightmapWidth;
int h = dat.heightmapHeight;
float[,] heights = dat.GetHeights(0,0,w,h);//Get the whole heightmap as a matrix of floats
for(int i=0;i<w;i++)
{
for(int j=0;j<h;j++)
{
if(i*map.width+j<mapColors.Length)
{
heights[i,j]=mapColors[i*map.width+j].b*factor;
}
}
}
// set the new height
dat.SetHeights(0,0,heights);
Debug.Log(uint.MaxValue);
}
catch(UnityException ex)
{
EditorUtility.DisplayDialog("Error!","Please set texture to readable","OK");
Debug.Log(ex.Message);
}
}
}