Trying To Apply Noise To Multiple Terrains

Having some issues trying to get a noise texture to apply to multiple terrains at once.

Basically I’ve got an 8000x8000 map, made up of 64 x 1000x1000 terrains. These are stored in a 2d array (terrains). Each one has a heightmap resolution of 256x256.

I’ve created a 2048x2048 noise texture which I’m attempting to break up into 64 smaller maps to use on each terrain. I’m hoping that this will spread the noise texture across all terrains, making seamless slopes.

I keep getting “Index was outside the bounds of the array” pop up when I run the game though. It says line 107 is the problem but I can’t see the issue anywhere. Basically the first terrain in the array gets correctly noised but that’s all that happens. Hoping a fresh set of eyes can point out what I’m sure is a really obvious mistake here! Cheers.

(Also if this method won’t actually give me the results I want then please let me know. I just improvised this from a tutorial for applying to a single terrain so no idea if it’s going to actually work as desired).

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class NoiseManage : MonoBehaviour
{
    public RawImage masterNoise;
    public RawImage holderNoise;

    public int masterW = 2048;
    public int masterH = 2048;
    public int singleW = 256;
    public int singleH = 256;

    [Range(0, 20)]
    public int seed;
    public int lastSeed;

    public GameObject terrainsHolder;

    [Range(0.01f, 0.3f)]
    public float scale;
    public float lastScale;

    private Noise _noise;

    public Terrain[,] terrains = new Terrain[8, 8];

    public float[,,] miniNoise;

    private void Awake()
    {
        scale = 0.02f;
        seed = 1;
        miniNoise = new float[singleW, singleH, 64];

        _noise = new PerlinNoise();      
        int childIndex = 0;
        for(int y = 0; y < 8; y++)
        {
            for(int x = 0; x < 8; x++)
            {
                terrains[x, y] = terrainsHolder.transform.GetChild(childIndex).GetComponent<Terrain>();              
                childIndex++;
            }
        }
        lastSeed = seed;
        lastScale = scale;

        ComputeMasterNoise();
    }
 

    private void ComputeMasterNoise()
    {
        _noise.seed = seed;
        float[,] noise = new float[masterW, masterH];
        for(int y = 0; y < masterH; y++)
        {
            for(int x = 0; x < masterW; x++)
            {
                noise[y, x] = _noise.GetNoiseMap(x, y, scale);
            }
        }      

        ComputeMiniNoise(noise);
    }

    private void ComputeMiniNoise(float[,] noise)
    {
        int ycount = 0;
        int xcount = 0;
        for(int z = 0; z < 64; z++)
        {
            for(int y = 0; y < singleH; y++)
            {
                for(int x = 0; x < singleW; x++)
                {
                    miniNoise[x, y, z] = noise[x + xcount * singleW, y + ycount * singleH];
                }
            }
            xcount++;
          
            if(xcount == 8)
            {
                xcount = 0;
                ycount++;
            }
        }
        SetNoise(miniNoise);
    }

    private void SetNoise(float[,,] noises)
    {
        for(int y = 0; y < 8; y++)
        {
            for(int x = 0; x < 8; x++)
            {
                Color[] pixels = new Color[singleW * singleH];              
                float[,] tempNoise = new float[singleW, singleH];
                for(int Y = 0; Y < singleH; Y++)
                {
                    for(int X = 0; X < singleW; X++)
                    {
                        pixels[X + singleW * Y] = Color.Lerp(Color.black, Color.white, noises[Y, X, x + y * 8]);
                        tempNoise[X, Y] = noises[X + x * singleW, Y + y * singleH, x + y * 8];
                    }
                }
                Texture2D texture = new Texture2D(singleW, singleH);
                texture.SetPixels(pixels);
                texture.Apply();
                holderNoise.texture = texture;
                terrains[x, y].terrainData.SetHeights(0, 0, tempNoise);
              
            }
        }
    }

One suggestion is to put a Debug.Log in the line before the error occurs to log the suspected variable values. It makes it easier to know whats going on.

Thanks for the idea! After spamming myself with over 18000 debug.logs I found where I’d made the error.

It doesn’t work as expected unfortunately :confused: back to tinkering with the variables.

1 Like