Search Unity

Other help IndexOutOfRangeException

Discussion in 'Scripting' started by lev_321, Feb 14, 2024.

  1. lev_321

    lev_321

    Joined:
    Jul 20, 2021
    Posts:
    5
    I spend 6 hours trying fix this code
    but no result


    help pls error:
    IndexOutOfRangeException: Index was outside the bounds of the array.
    TerrainGeneration.PlaceTile (UnityEngine.Sprite tileSprite, System.Int32 x, System.Int32 y) (at Assets/TerrainGeneration.cs:186)
    TerrainGeneration.GenerateTerrain () (at Assets/TerrainGeneration.cs:115)
    TerrainGeneration.Start () (at Assets/TerrainGeneration.cs:64)

    in this video generating 5 chunks with index 0,1,2,3,4


    code from this video:


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class TerrainGeneration : MonoBehaviour
    6. {
    7.  
    8.  
    9.     [Header("                   World Settings")]
    10.     [Header(" ")]
    11.  
    12.  
    13.     [Header("              General World Settings")]
    14.     public float seed;
    15.     public int worldSize = 100;
    16.     public int treeChance = 10;
    17.     public bool generateCaves = true;
    18.     [Header(" ")]
    19.  
    20.  
    21.     [Header("               Other World Settings")]
    22.     public int minTreeHeight = 5;
    23.     public int maxTreeHeight = 7;
    24.     public int dirtLayerHeight = 5;
    25.     public float surfaceValue = 0.25f;
    26.     public float caveFreq = 0.08f;
    27.     public float terrainFreq = 0.04f;
    28.     public float heightMultiplier = 25f;
    29.     public int heightAddition = 25;
    30.     public int chunkSize = 16;
    31.     [Header(" ")]
    32.  
    33.     [Header("                           Noise")]
    34.     public Texture2D noiseTexture;
    35.     [Header(" ")]
    36.  
    37.  
    38.     [Header("                   Texture Settings")]
    39.     [Header(" ")]
    40.     public Sprite leaf;
    41.     public Sprite log;
    42.     public Sprite grass;
    43.     public Sprite dirt;
    44.     public Sprite stone;
    45.  
    46.     [Header("?")]
    47.     public GameObject[] worldChunks;
    48.     public List<Vector2> worldTiles = new List<Vector2>();
    49.  
    50.     private void Start()
    51.     {
    52.         if (seed == 0)
    53.         {
    54.             seed = Random.Range(-10000, 10000);
    55.             GenerateNoiseTexture();
    56.             CreateChunks();
    57.             GenerateTerrain();
    58.  
    59.         }
    60.         else
    61.         {
    62.             GenerateNoiseTexture();
    63.             CreateChunks();
    64.             GenerateTerrain();
    65.         }
    66.     }
    67.  
    68.     public void CreateChunks()
    69.     {
    70.         int numChunks = worldSize / chunkSize;
    71.         worldChunks = new GameObject[numChunks];
    72.  
    73.         for (int i = 0; i < numChunks; i++)
    74.         {
    75.             GameObject newChunk = new GameObject();
    76.            newChunk.name = i.ToString();
    77.            newChunk.transform.parent = this.transform;
    78.            worldChunks[i] = newChunk;
    79.         }
    80.     }
    81.  
    82.     public void GenerateTerrain()
    83.     {
    84.         for (int x = 0; x < worldSize; x++)
    85.         {
    86.             float height = Mathf.PerlinNoise((x + seed) * terrainFreq, seed * terrainFreq) * heightMultiplier + heightAddition;
    87.  
    88.             for (int y = 0; y < height; y++)
    89.             {
    90.                 Sprite tileSprite;
    91.                 if (y < height - dirtLayerHeight)
    92.                 {
    93.                     tileSprite = stone;
    94.  
    95.                 }
    96.                 else if (y < height - 1)
    97.                 {
    98.                     tileSprite = dirt;
    99.                 }
    100.                 else
    101.                 {
    102.                     tileSprite = grass;
    103.                 }
    104.                 if (generateCaves)
    105.                 {
    106.  
    107.  
    108.                     if (noiseTexture.GetPixel(x, y).r > surfaceValue)
    109.                     {
    110.                         PlaceTile(tileSprite, x, y);
    111.                     }
    112.                 }
    113.                 else
    114.                 {
    115.                     PlaceTile(tileSprite, x, y);
    116.                 }
    117.                 if (y >= height - 1)
    118.                 {
    119.                     int t = Random.Range(0, treeChance);
    120.  
    121.  
    122.                     if (t == 1)
    123.                     {
    124.                         if (worldTiles.Contains(new Vector2(x, y)))
    125.                         {
    126.                             GenerateTree(x, y + 1);
    127.                         }
    128.                     }
    129.                 }
    130.             }
    131.         }
    132.     }
    133.  
    134.  
    135.     public void GenerateNoiseTexture()
    136.     {
    137.         noiseTexture = new Texture2D(worldSize, worldSize);
    138.  
    139.         for (int x = 0; x < noiseTexture.width; x++)
    140.         {
    141.             for (int y = 0; y < noiseTexture.height; y++)
    142.             {
    143.                 float v = Mathf.PerlinNoise((x + seed) * caveFreq, (y + seed) * caveFreq);
    144.                 noiseTexture.SetPixel(x, y,new Color(v, v, v));
    145.             }
    146.         }
    147.         noiseTexture.Apply();
    148.     }
    149.  
    150.     public void GenerateTree(int x, int y)
    151.     {
    152.         int treeHeight = Random.Range(minTreeHeight, maxTreeHeight);
    153.         for (int i = 0; i < treeHeight; i++)
    154.         {
    155.             PlaceTile(log, x, y + i);
    156.         }
    157.         //1
    158.         PlaceTile(leaf, x - 1, y + treeHeight);
    159.         PlaceTile(leaf, x, y + treeHeight);
    160.         PlaceTile(leaf, x + 1, y + treeHeight);
    161.         //2
    162.         PlaceTile(leaf, x - 1, y + treeHeight - 1);
    163.         PlaceTile(leaf, x, y + treeHeight - 1);
    164.         PlaceTile(leaf, x + 1, y + treeHeight - 1);
    165.         //3
    166.         PlaceTile(leaf, x - 2, y + treeHeight - 2);
    167.         PlaceTile(leaf, x - 1, y + treeHeight - 2);
    168.         PlaceTile(leaf, x, y + treeHeight - 2);
    169.         PlaceTile(leaf, x + 1, y + treeHeight - 2);
    170.         PlaceTile(leaf, x + 2, y + treeHeight - 2);
    171.         //4
    172.         PlaceTile(leaf, x - 2, y + treeHeight - 3);
    173.         PlaceTile(leaf, x - 1, y + treeHeight - 3);
    174.         PlaceTile(leaf, x, y + treeHeight - 3);
    175.         PlaceTile(leaf, x + 1, y + treeHeight - 3);
    176.         PlaceTile(leaf, x + 2, y + treeHeight - 3);
    177.     }
    178.  
    179.  
    180.     public void PlaceTile(Sprite tileSprite, int x, int y)
    181.     {
    182.         GameObject newTile = new GameObject();
    183.  
    184.         float  chunkCoord = (Mathf.Round(x / chunkSize));
    185.         Debug.Log(chunkCoord);
    186.         newTile.transform.parent = worldChunks[(int)chunkCoord].transform;
    187.    
    188.  
    189.         newTile.AddComponent<SpriteRenderer>();
    190.         newTile.GetComponent<SpriteRenderer>().sprite = tileSprite;
    191.         newTile.name = tileSprite.name;
    192.         newTile.transform.position = new Vector2(x + 0.5f, y + 0.5f);
    193.  
    194.         worldTiles.Add(newTile.transform.position - (Vector3.one * 0.5f));
    195.     }
    196. }
    197.  
    198.  
     
    Last edited: Feb 14, 2024
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    Here are some notes on IndexOutOfRangeException and ArgumentOutOfRangeException:

    http://plbm.com/?p=236

    Steps to success:
    - find which collection it is and what line of code accesses it <--- (critical first step!)
    - find out why it has fewer items than you expect
    - fix whatever logic is making the indexing value exceed the collection size
    - remember that a collection with ZERO elements cannot be indexed at all: it is empty
    - remember you might have more than one instance of this script in your scene/prefab
    - remember the collection may be used in more than one location in the code
    - remember that indices start at ZERO (0) and go to the count / length minus 1.

    This means with three (3) elements in your collection, they are numbered 0, 1, and 2 only.
     
    Ryiah likes this.
  3. dave_g_69

    dave_g_69

    Joined:
    Jul 24, 2021
    Posts:
    28
    just a quick look, but when worldsize >= 96 (you set it to 100 so this would be true)
    Code (CSharp):
    1. float  chunkCoord = (Mathf.Round(x / chunkSize));
    will == 6, when x is greater than or equal to 96. (96/16 ==6)

    your worldChunks[(int)chunkCoord] can only index from 0-5. so you need a better way to calculate the chunk coord. so it will only return 0 through to (maxChunkCoords-1). may need to adjust your worldsize to a value predictably divisible by chunksize.
     
    Ryiah likes this.