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:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeshGenerator : MonoBehaviour
{
Mesh mesh;
Vector3[] vertices;
int[] triangles;
public int Size = 20;
public float scale = 0.3f;
public int octaves;
public float presistance;
public float lacunarity;
public int seed;
public Vector2 offset;
public TerrainType[] regions;
Texture2D texture;
Vector2[] uvs;
public Material mat;
public float heightMultiplier = 20f;
public AnimationCurve curve;
float[,] heightMap;
public GameObject treePrefab;
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
mesh.name = "Mesh";
heightMap = GenerateNoiseMap(Size, scale, seed, octaves, presistance, lacunarity, offset);
CreateShape();
UpdateMesh();
}
void CreateShape()
{
vertices = new Vector3[(Size + 1) * (Size + 1)];
Color[] colourMap = new Color[(Size + 1) * (Size + 1)];
float[,] treeHeightMap = GenerateNoiseMap(Size, scale, seed + 3, octaves, presistance, lacunarity, offset);
for (int i = 0, z = 0; z <= Size; z++)
{
for (int x = 0; x <= Size; x++)
{
float currentHeight = curve.Evaluate(heightMap[x, z]) * heightMultiplier;
for (int j = 0; j < regions.Length; j++)
{
if (currentHeight <= regions[j].height)
{
colourMap[z * Size + x] = regions[j].colour;
}
}
if (treeHeightMap[x, z] >= .5f && currentHeight > 2)
{
GameObject tree = Instantiate(treePrefab);
tree.transform.position = new Vector3(x, currentHeight, z);
}
vertices[i] = new Vector3(x, currentHeight, z);
i++;
}
}
texture = new Texture2D(Size, Size);
texture.SetPixels(colourMap);
texture.filterMode = FilterMode.Point;
texture.wrapMode = TextureWrapMode.Clamp;
texture.Apply();
mat.mainTexture = texture;
triangles = new int[Size * Size * 6];
int vert = 0;
int tris = 0;
for (int z = 0; z < Size; z++)
{
for (int x = 0; x < Size; x++)
{
triangles[tris] = vert;
triangles[tris + 1] = vert + Size + 1;
triangles[tris + 2] = vert + 1;
triangles[tris + 3] = vert + 1;
triangles[tris + 4] = vert + Size + 1;
triangles[tris + 5] = vert + Size + 2;
vert++;
tris += 6;
}
vert++;
}
uvs = new Vector2[vertices.Length];
for (int i = 0, z = 0; z <= Size; z++)
{
for (int x = 0; x <= Size; x++)
{
uvs[i] = new Vector2((float)x / Size, (float)z / Size);
i++;
}
}
}
void UpdateMesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
mesh.RecalculateNormals();
GetComponent<MeshCollider>().sharedMesh = mesh;
}
float[,] GenerateNoiseMap(int size, float scale, int seed, int octaves, float presistance, float lacunarity, Vector2 offset)
{
float[,] noiseMap = new float[size + 1, size + 1];
System.Random prng = new System.Random(seed);
Vector2[] octaveOffsets = new Vector2[octaves + 1];
for (int i = 0; i <= octaves; i++)
{
float offsetX = prng.Next(-100000, 100000) + offset.x;
float offsetZ = prng.Next(-100000, 100000) + offset.y;
octaveOffsets[i] = new Vector2(offsetX, offsetZ);
}
if (scale <= 0)
{
scale = 0.0001f;
}
float minNoiseHeight = float.MaxValue;
float maxNoiseHeight = float.MinValue;
float halfSize = size / 2;
for (int z = 0; z <= size; z++)
{
for(int x = 0;x <= size; x++)
{
float amplitude = 1;
float frequency = 1;
float noiseHeight = 0;
for (int i = 0; i <= octaves; i++)
{
float sampleX = (x - halfSize) / scale * frequency + octaveOffsets[i].x;
float sampleY = (z - halfSize) / scale * frequency + octaveOffsets[i].y;
float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
noiseHeight += perlinValue * amplitude;
amplitude *= presistance;
frequency *= lacunarity;
}
if(noiseHeight < minNoiseHeight)
{
minNoiseHeight = noiseHeight;
}else if(noiseHeight > maxNoiseHeight)
{
maxNoiseHeight = noiseHeight;
}
noiseMap[x, z] = noiseHeight;
}
}
for (int z = 0; z <= size; z++)
{
for (int x = 0; x <= size; x++)
{
noiseMap[x, z] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x, z]);
float fallOffX = z / (float)size * 2 - 1;
float fallOffZ = x / (float)size * 2 - 1;
float value = Mathf.Max(Mathf.Abs(fallOffX), Mathf.Abs(fallOffZ));
noiseMap[x, z] = Mathf.Clamp01(noiseMap[x, z] - Evaluate(value));
}
}
return noiseMap;
}
float Evaluate(float value)
{
float a = 3;
float b = 2.2f;
return Mathf.Pow(value, a) / (Mathf.Pow(value, a) + Mathf.Pow(b - b * value, a));
}
[System.Serializable]
public struct TerrainType
{
public string name;
public float height;
public Color colour;
}
}
Thank you for all the answers