Skip to content
Snippets Groups Projects
Select Git revision
  • 531cca3ac3340ae4fde8e995e1abacaf640643b5
  • main default protected
2 results

V7.cs

Blame
  • 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);
        }
    }