Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Resolved Bad mesh shape and flying trees

Discussion in 'Scripting' started by unity_14F7DC29A95C66D833DC, May 18, 2024.

  1. unity_14F7DC29A95C66D833DC

    unity_14F7DC29A95C66D833DC

    Joined:
    Sep 18, 2021
    Posts:
    9
    Hi, I have a problem that my mesh which is supposed to be a square but is a rectangle which is strange because I am creating vertexes in a square and not in a rectangle and because of this I have no idea how to generate trees on the excess part, does anyone know how to make the mesh square? Also my trees are flying in the air for some reason.

    code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class MeshGenerator : MonoBehaviour
    6. {
    7.     Mesh mesh;
    8.  
    9.     Vector3[] vertices;
    10.     int[] triangles;
    11.  
    12.     public int Size = 20;
    13.  
    14.     public float scale = 0.3f;
    15.  
    16.     public int octaves;
    17.     public float presistance;
    18.     public float lacunarity;
    19.  
    20.     public int seed;
    21.     public Vector2 offset;
    22.  
    23.     public TerrainType[] regions;
    24.  
    25.     Texture2D texture;
    26.  
    27.     Vector2[] uvs;
    28.  
    29.     public Material mat;
    30.     public float heightMultiplier = 20f;
    31.  
    32.     public AnimationCurve curve;
    33.  
    34.     float[,] heightMap;
    35.  
    36.     public GameObject treePrefab;
    37.  
    38.     void Start()
    39.     {
    40.         mesh = new Mesh();
    41.         GetComponent<MeshFilter>().mesh = mesh;
    42.         mesh.name = "Mesh";
    43.  
    44.         heightMap = GenerateNoiseMap(Size, scale, seed, octaves, presistance, lacunarity, offset);
    45.  
    46.         CreateShape();
    47.         UpdateMesh();
    48.  
    49.     }
    50.  
    51.     void CreateShape()
    52.     {
    53.         vertices = new Vector3[(Size + 1) * (Size + 1)];
    54.         Color[] colourMap = new Color[(Size + 1) * (Size + 1)];
    55.  
    56.         float[,] treeHeightMap = GenerateNoiseMap(Size, scale, seed + 3, octaves, presistance, lacunarity, offset);
    57.  
    58.         for (int i = 0, z = 0; z <= Size; z++)
    59.         {
    60.             for (int x = 0; x <= Size; x++)
    61.             {              
    62.                 float currentHeight = curve.Evaluate(heightMap[x, z]) * heightMultiplier;
    63.  
    64.                 for (int j = 0; j < regions.Length; j++)
    65.                 {
    66.                     if (currentHeight <= regions[j].height)
    67.                     {
    68.                         colourMap[z * Size + x] = regions[j].colour;
    69.                     }
    70.                 }
    71.  
    72.                 if (treeHeightMap[x, z] >= .5f && currentHeight > 2)
    73.                 {
    74.                     GameObject tree = Instantiate(treePrefab);
    75.  
    76.                     tree.transform.position = new Vector3(x, currentHeight, z);
    77.                 }
    78.  
    79.                 vertices[i] = new Vector3(x, currentHeight, z);
    80.                 i++;
    81.             }
    82.         }
    83.  
    84.         texture = new Texture2D(Size, Size);
    85.         texture.SetPixels(colourMap);
    86.         texture.filterMode = FilterMode.Point;
    87.         texture.wrapMode = TextureWrapMode.Clamp;
    88.         texture.Apply();
    89.  
    90.         mat.mainTexture = texture;
    91.  
    92.         triangles = new int[Size * Size * 6];
    93.  
    94.         int vert = 0;
    95.         int tris = 0;
    96.  
    97.         for (int z = 0; z < Size; z++)
    98.         {
    99.             for (int x = 0; x < Size; x++)
    100.             {
    101.                 triangles[tris] = vert;
    102.                 triangles[tris + 1] = vert + Size + 1;
    103.                 triangles[tris + 2] = vert + 1;
    104.                 triangles[tris + 3] = vert + 1;
    105.                 triangles[tris + 4] = vert + Size + 1;
    106.                 triangles[tris + 5] = vert + Size + 2;
    107.  
    108.                 vert++;
    109.                 tris += 6;
    110.             }
    111.             vert++;
    112.         }
    113.  
    114.         uvs = new Vector2[vertices.Length];
    115.         for (int i = 0, z = 0; z <= Size; z++)
    116.         {
    117.             for (int x = 0; x <= Size; x++)
    118.             {
    119.                 uvs[i] = new Vector2((float)x / Size, (float)z / Size);
    120.                 i++;
    121.             }
    122.         }
    123.     }
    124.  
    125.     void UpdateMesh()
    126.     {
    127.         mesh.Clear();
    128.  
    129.         mesh.vertices = vertices;
    130.         mesh.triangles = triangles;
    131.         mesh.uv = uvs;
    132.  
    133.         mesh.RecalculateNormals();
    134.  
    135.         GetComponent<MeshCollider>().sharedMesh = mesh;
    136.     }
    137.  
    138.     float[,] GenerateNoiseMap(int size, float scale, int seed, int octaves, float presistance, float lacunarity, Vector2 offset)
    139.     {
    140.         float[,] noiseMap = new float[size + 1, size + 1];
    141.  
    142.         System.Random prng = new System.Random(seed);
    143.         Vector2[] octaveOffsets = new Vector2[octaves + 1];
    144.  
    145.         for (int i = 0; i <= octaves; i++)
    146.         {
    147.             float offsetX = prng.Next(-100000, 100000) + offset.x;
    148.             float offsetZ = prng.Next(-100000, 100000) + offset.y;
    149.  
    150.             octaveOffsets[i] = new Vector2(offsetX, offsetZ);
    151.         }
    152.  
    153.         if (scale <= 0)
    154.         {
    155.             scale = 0.0001f;
    156.         }
    157.  
    158.         float minNoiseHeight = float.MaxValue;
    159.         float maxNoiseHeight = float.MinValue;
    160.  
    161.         float halfSize = size / 2;
    162.  
    163.         for (int z = 0; z <= size; z++)
    164.         {
    165.             for(int x = 0;x <= size; x++)
    166.             {
    167.  
    168.                 float amplitude = 1;
    169.                 float frequency = 1;
    170.                 float noiseHeight = 0;
    171.  
    172.                 for (int i = 0; i <= octaves; i++)
    173.                 {
    174.                     float sampleX = (x - halfSize) / scale * frequency + octaveOffsets[i].x;
    175.                     float sampleY = (z - halfSize) / scale * frequency + octaveOffsets[i].y;
    176.  
    177.                     float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
    178.                     noiseHeight += perlinValue * amplitude;
    179.  
    180.                     amplitude *= presistance;
    181.                     frequency *= lacunarity;
    182.                 }
    183.  
    184.                 if(noiseHeight < minNoiseHeight)
    185.                 {
    186.                     minNoiseHeight = noiseHeight;
    187.                 }else if(noiseHeight > maxNoiseHeight)
    188.                 {
    189.                     maxNoiseHeight = noiseHeight;
    190.                 }
    191.  
    192.                 noiseMap[x, z] = noiseHeight;
    193.             }
    194.         }
    195.  
    196.         for (int z = 0; z <= size; z++)
    197.         {
    198.             for (int x = 0; x <= size; x++)
    199.             {
    200.                 noiseMap[x, z] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x, z]);
    201.  
    202.                 float fallOffX = z / (float)size * 2 - 1;
    203.                 float fallOffZ = x / (float)size * 2 - 1;
    204.  
    205.                 float value = Mathf.Max(Mathf.Abs(fallOffX), Mathf.Abs(fallOffZ));
    206.  
    207.                 noiseMap[x, z] = Mathf.Clamp01(noiseMap[x, z] - Evaluate(value));
    208.             }
    209.         }
    210.  
    211.         return noiseMap;
    212.     }
    213.  
    214.     float Evaluate(float value)
    215.     {
    216.         float a = 3;
    217.         float b = 2.2f;
    218.  
    219.         return Mathf.Pow(value, a) / (Mathf.Pow(value, a) + Mathf.Pow(b - b * value, a));
    220.     }
    221.  
    222.     [System.Serializable]
    223.     public struct TerrainType
    224.     {
    225.         public string name;
    226.         public float height;
    227.         public Color colour;
    228.     }
    229. }
    Thank you for all the answers

    procGenY.png procGenTrees.png
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,371
    Sounds like a bug, maybe more than one bug! That means it is time to start debugging.

    By debugging you can find out exactly what your program is doing so you can fix it.

    https://docs.unity3d.com/Manual/ManagedCodeDebugging.html

    Use the above techniques to get the information you need in order to reason about what the problem is.

    You can also use
    Debug.Log(...);
    statements to find out if any of your code is even running. Don't assume it is.

    Once you understand what the problem is, you may begin to reason about a solution to the problem.


    For something like the above, simplify, simplify, simplify.

    - make your terrain one single quad
    - make one single tree in the center of it.

    Until that works I think we all agree nothing more complicated can work.
     
  3. unity_14F7DC29A95C66D833DC

    unity_14F7DC29A95C66D833DC

    Joined:
    Sep 18, 2021
    Posts:
    9
    Ok
     
  4. unity_14F7DC29A95C66D833DC

    unity_14F7DC29A95C66D833DC

    Joined:
    Sep 18, 2021
    Posts:
    9
    I don't know why, but it worked when I created a new project and for some reason the mesh was square