Home > Net >  Unity Map generation and colors
Unity Map generation and colors

Time:12-01

I am currently following a Brackeys tutorial on procedural terrain generation colors. I got to a point where it gives me this error:

IndexOutOfRangeException: Index was outside the bounds of the array. mapgeneration.CreateShape () (at Assets/mapgeneration.cs:108 mapgeneration.Update () (at Assets/mapgeneration.cs:131)

I am using gradients to display color on line 108 in CreateShape. This is the line:

colors[iloopedforvertecy] = gradient.Evaluate(height);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshFilter))]
public class mapgeneration : MonoBehaviour
{ 
    Mesh mesh;
    Color[] colors;
     
    Vector3[] vertices;
    int[] triangles;

    public int xsize = 20;
    public int zsize = 20;
    [Range(1, 100)]
    public float smooth = 1.0f;
    public MeshCollider _mesh;

    public Transform water;
    public float scale;
    public float smoothfactor;
    
    public float xoffset = 0.0f;
    public float zoffset = 0.0f;

    public float minwaterheight;
    public float maxwaterheight;

    public float minterainheight;
    public float maxterainheight;
    public Gradient gradient;

    // Start is called before the first frame update
    void Start()
    {
       mesh = new Mesh();
       GetComponent<MeshFilter>().mesh = mesh;
    
       CreateShape();
       _mesh = GetComponent<MeshCollider>();
      
       water.transform.position = new Vector3(0, Random.Range(minwaterheight, maxwaterheight), 0);
    }
    
    void CreateShape()
    {
        vertices = new Vector3[(xsize   1) * (zsize   1)];
        water.transform.localScale = new Vector3(xsize, 0, zsize);
        int iloopedforvertecy = 0;
    
        triangles = new int[xsize * zsize * 6];
        int vert = 0;
        int tris = 0;
    
        for(int z = 0; z < zsize; z  )
        {
            for(int x = 0; x < xsize; x  )
            {
                triangles[tris   0] = vert   0;
                triangles[tris   1] = vert   xsize   1;
                triangles[tris   2] = vert   1;
                triangles[tris   3] = vert   1;
                triangles[tris   4] = vert   xsize   1;
                triangles[tris   5] = vert   xsize   2;
    
                vert  ;
                tris  = 6;
            }  
            vert  ;
        }
    
        colors = new Color[vertices.Length];
    
        for (int z = 0; z <= zsize; z  )
        {
            for(int x = 0; x <= xsize; x  )
            {
                float xCoord = (float)x / xsize * scale   xoffset;
                float zCoord = (float)z / zsize * scale   zoffset;
             
                float y =  Mathf.PerlinNoise(xCoord * smooth, zCoord * smooth) * smoothfactor;
               
                vertices[iloopedforvertecy] = new Vector3(x, y, z);
                iloopedforvertecy  = 1;

                if(y > maxterainheight)
                {
                    maxterainheight = y;
                }
    
                if(y < minterainheight)
                {
                    minterainheight = y;
                }
    
                float height = Mathf.InverseLerp(minterainheight, maxterainheight, 0.5f); //vertices[iloopedforvertecy].z
                Debug.LogWarning(height);
                colors[iloopedforvertecy] = gradient.Evaluate(height);
            }
        }
    }

    void UpdateMsh()
    {
        mesh.Clear();

        mesh.vertices = vertices;
        mesh.triangles = triangles;

        mesh.RecalculateNormals();
        
        mesh.colors = colors;
    }

    void Update()
    {
        CreateShape();
        UpdateMsh();
    } 
}

I know that my code is messy. Still new to coding and unity in general.

Oh PS. Can somebody please help me add a collider to code generated object as you can see in the code above?

CodePudding user response:

In your for-loop you increase the value of iloopedforvertecy before you evaluate your gradient value. Because of this the last value of iloopedforvertecy will be greater than the array length of your colors array.

Try to move the line which increases the value at the end of the loop

for(int x = 0; x <= xsize; x  )
{
    float xCoord = (float)x / xsize * scale   xoffset;
    float zCoord = (float)z / zsize * scale   zoffset;
             
    float y =  Mathf.PerlinNoise(xCoord * smooth, zCoord * smooth) * smoothfactor;
               
    vertices[iloopedforvertecy] = new Vector3(x, y, z);
    // iloopedforvertecy  = 1; // HERE THE VALUE WAS INCREASED

    if(y > maxterainheight)
    {
        maxterainheight = y;
    }
    
    if(y < minterainheight)
    {
        minterainheight = y;
    }
    
    float height = Mathf.InverseLerp(minterainheight, maxterainheight, 0.5f); //vertices[iloopedforvertecy].z
    Debug.LogWarning(height);
    colors[iloopedforvertecy] = gradient.Evaluate(height);
    iloopedforvertecy  = 1; // HERE SHOULD THE VALUE BE INCREASED

}

In the example here I commented the two lines.

CodePudding user response:

The error you recieve means that the array colors[] is not big enough.

I don't know what you are trying to achieve and doesn't have the rest of your code, so I will assume you can just pump ups the array size that way

 colors = new Color[((xsize   1) * (zsize   1)) * 2];

I did a monstruous bump, so you will need to put something that fits your need instead of that multiplication by 2

  • Related