Select Git revision
V7.cs 8.93 KiB
/*
Clément Géraudie
*/
using UnityEngine;
public class V7 : MonoBehaviour
{
[Header("Debug Mode")]
public bool debugMode = false;
[Header("Initialisation")]
public int nombreDePointsAGenerer = 5;
public int largeurDuChemin = 5;
public float offsetDeLaHauteur = -0.1f;
[Header("Terrain")]
[SerializeField] private Terrain terrain;
public int pronfondeurDuTerrain = 20;
// Constantes pour la heightmap
[SerializeField] private int heightmapWidth = 256;
[SerializeField] private int heightmapHeight = 256;
[SerializeField] private int terrainWidth = 256;
[SerializeField] private int terrainHeight = 256;
public float scale = 2f;
public int[,] pointsDuChemin;
public int[] ptProches;
int ptsChemAbscisse;
int ptsChemIndex;
//public float offsetX = 100f;
//public float offsetY = 100f;
void Start()
{
// Création du tableau des points aléatoires (chemin)
pointsDuChemin = new int[2, nombreDePointsAGenerer];
// Récupère les dimensions du tableau de manière optimisée
ptsChemAbscisse = pointsDuChemin.GetLength(0);
ptsChemIndex = pointsDuChemin.GetLength(1);
// On va générer les points de sorte à ce qu'il ne puissent pas se croiser
// On va découper le terrain en N partie, n étant le nombre de pts à générer
int lastBorder = 0;
int newBorder;
for (int abscisse = 0; abscisse < ptsChemAbscisse; abscisse++)
{
for (int indexPt = 0; indexPt < ptsChemIndex; indexPt++)
{
if(abscisse==1){
// Si abscisse = 1, ça veut dire qu'on est sur l'axe Y du terrain
newBorder = (heightmapWidth / nombreDePointsAGenerer) + lastBorder; // On calcule dynamiquement la taille de la zone de terrain où l'on va générer le pt
pointsDuChemin[abscisse, indexPt] = Random.Range(lastBorder, newBorder); // On génère un pt aléatoire dans la zone définie
// Debug.Log("Point Y=" + pointsDuChemin[x, y]);
lastBorder = newBorder; // On met à jour la zone de terrain où l'on va générer le pt
}else{
// Normalement, on est sur 0 (c'set un tableau de taille 2)
pointsDuChemin[abscisse, indexPt] = Random.Range(0, heightmapWidth);
// Debug.Log("Point X=" + pointsDuChemin[x, y]);
}
}
}
// On va récupérer le terrain et on va générer sa forme
terrain = GetComponent<Terrain>();
terrain.terrainData = GenerateTerrain(terrain.terrainData);
// On va faire quelques vérifications
if(terrain == null)
{
Debug.LogError("Terrain non trouvé");
return;
}
if(terrain.terrainData == null)
{
Debug.LogError("TerrainData non trouvé");
return;
}
// On va tracer le chemin
tracerChemin();
}
TerrainData GenerateTerrain(TerrainData terrainData)
{
terrainData.heightmapResolution = heightmapWidth + 1;
terrainData.size = new Vector3(terrainWidth, pronfondeurDuTerrain, terrainHeight);
terrainData.SetHeights(0, 0, GenerateHeights());
return terrainData;
}
/*void ptLePlusProche()
{
int ptProche = -1;
double resultPtProche = 256;
double resultPtActuel = 256;
ptProches = new int[ptsCheminY];
for (int i = 0; i < ptsCheminY; i++)
{
for (int j = 0; j < ptsCheminY; j++)
{
if (pointsDuChemin[0, j] != pointsDuChemin[0, i] || pointsDuChemin[1, j] != pointsDuChemin[1, i])
{
int x1 = pointsDuChemin[0, i];
int y1 = pointsDuChemin[1, i];
int x2 = pointsDuChemin[0, j];
int y2 = pointsDuChemin[1, j];
resultPtActuel = Mathf.Sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2);
if (resultPtActuel < resultPtProche)
{
resultPtProche = resultPtActuel;
ptProche = j;
}
}
}
ptProches[i] = ptProche;
}
// Debug liste de ptProches
for (int i = 0; i < ptsCheminY; i++)
{
Debug.Log("ptProches[" + i + "] = " + ptProches[i]);
}
}*/
// Tracer chemin va se charger de dessinner le chemin au sol
private void tracerChemin()
{
// On va parcourir les pointsDuChemin et tracer le chemin entre ces points
for(int i=0; i<nombreDePointsAGenerer-1; i++)
{
// Debug.Log("Point 1 : " + pointsDuChemin[0, i] + " " + pointsDuChemin[1, i]);
// Debug.Log("Point 2 : " + pointsDuChemin[0, i+1] + " " + pointsDuChemin[1, i+1]);
tracerChemin(pointsDuChemin[0, i], pointsDuChemin[1, i], pointsDuChemin[0, i+1], pointsDuChemin[1, i+1]);
}
}
private void tracerChemin(int x1, int y1, int x2, int y2)
{
int x = x1;
int y = y1;
// On va faire un lerp entre les points
float lerp = 0f;
while(lerp < 1f)
{
lerp += 0.01f;
x = Mathf.RoundToInt(Mathf.Lerp(x1, x2, lerp));
y = Mathf.RoundToInt(Mathf.Lerp(y1, y2, lerp));
//Debug.Log("x = " + x + " y = " + y);
float hauteur, hauteurAvant, hauteurApres;
// On va tracer le chemin en largeur
for(int i=0; i<largeurDuChemin; i++)
{
if(x+i < heightmapWidth && y+i < heightmapHeight)
{
// On va calculer la hauteur du point par rapport aux coordonées d'avant, et d'après
if(x+i-1 < 0 || y+i-1 < 0){
hauteurAvant = 0;
}else{
hauteurAvant = terrain.terrainData.GetHeight(x+i-1, y+i-1);
}
if(x+i+1 >= heightmapWidth || y+i+1 >= heightmapHeight){
hauteurApres = 0;
}else{
hauteurApres = terrain.terrainData.GetHeight(x+i+1, y+i+1);
}
// On va faire la moyenne des deux hauteurs si elles sont != 0
if(hauteurAvant != 0 && hauteurApres != 0){
hauteur = (hauteurAvant + hauteurApres) / 2;
}else if(hauteurAvant != 0){
hauteur = hauteurAvant;
}else if(hauteurApres != 0){
hauteur = hauteurApres;
}else{
hauteur = 0;
}
hauteur += offsetDeLaHauteur;
// On va changer l'échelle de la hauteur sur 1
hauteur = hauteur / terrain.terrainData.size.y;
Debug.Log("hauteur = " + hauteur);
terrain.terrainData.SetHeights(x+i, y+i, new float[,] { { hauteur, hauteur }});
}
}
}
}
void OnDrawGizmosSelected()
{
if(debugMode){
// On définie les paramètres de la gizmo sphere
Gizmos.color = Color.red;
if(pointsDuChemin != null)
{
float xPositionMultiplier = terrain.terrainData.size.x / heightmapWidth;
float yPositionMultiplier = terrain.terrainData.size.z / heightmapHeight;
// On va tracer une gizmo sphere sur chaque point du chemin
for(int i=0; i<nombreDePointsAGenerer; i++)
{
Gizmos.DrawSphere(new Vector3(pointsDuChemin[0, i] * xPositionMultiplier, 0, pointsDuChemin[1, i] * yPositionMultiplier), largeurDuChemin);
}
}
}
}
float[,] GenerateHeights()
{
// On initialise le tableau
float[,] terrainHeightsList = new float[heightmapWidth, heightmapHeight];
// On remplit le tableau
for (int x = 0; x < heightmapWidth; x++)
{
for (int y = 0; y < heightmapHeight; y++)
{
// On calcule hauteur
terrainHeightsList[x, y] = CalculateHeight(x, y);
}
}
// Pour chaque point à générer, on va définir la hauteur à 0
for (int i = 0; i < nombreDePointsAGenerer; i++)
{
terrainHeightsList[pointsDuChemin[1, i], pointsDuChemin[0, i]] = 0; // terrainHeightsList[ ptPosX, ptPosY ] = 0;
}
return terrainHeightsList;
}
// Renvoie une valeur semi-aléaoite (perlin noise) entre un point x et y
float CalculateHeight(int x, int y)
{
float xCoord = (float)x / heightmapWidth * scale;//+ offsetX;
float yCoord = (float)y / heightmapHeight * scale;//+ offsetY;
return Mathf.PerlinNoise(xCoord, yCoord);
}
}