Search Unity

Question Help with lists

Discussion in 'Scripting' started by eeveahy-x, Sep 26, 2022.

  1. eeveahy-x

    eeveahy-x

    Joined:
    Mar 12, 2022
    Posts:
    14
    I need a hand with picking out a random element from a list. I am attempting to spawn prefabs from a list (assigned in the inspector), using a list of Vector3 positions created by several raycasts, I will attach the full script separately as I believe it is not all the relevant.

    I am having an issue where the index chosen was out of range (ArgumentOutOfRangeException). I know the random position is the issue, and not the random prefab choice, as the code works if I instantiate at a chosen position.

    If I am using lists wrong, please let me know. Any help is appreciated.

    Code (CSharp):
    1.  void SpawnComponent()
    2.     {
    3.         for(matchCount = 0; matchCount < numberOfComponents; ++matchCount) //run the loop until the max components has been reached
    4.         {
    5.             int randomNum = Random.Range(0, spawnPositions.Count);
    6.             Vector3 chosenPosition = spawnPositions[randomNum];
    7.  
    8.             Debug.Log(chosenPosition); //for testing
    9.  
    10.             GameObject environmentpiece = Instantiate(environmentPrefabs[Random.Range(0,environmentPrefabs.Count)]/*this works*/,
    11.             chosenPosition/*this does not*/, Random.rotation);
    12.         }
    13.     }
    14. }
    full script

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CreateEnvironment : MonoBehaviour
    6. {
    7.     public List<GameObject> environmentPrefabs; //list of prefabs to randomly choose from
    8.     public List<Vector3> spawnPositions; //holds positions generated by rays
    9.     public GameObject centrePoint, thePlanet;
    10.     private Collider planetCollider;
    11.     public int numberOfComponents = 5; //max components in the scene
    12.     int matchCount, matchRay, rayCount = 6;
    13.     public LayerMask whatCanBeHit;
    14.    
    15.     void Start()
    16.     {
    17.         planetCollider = thePlanet.GetComponent<Collider>();
    18.  
    19.         RaycastHit hit;
    20.  
    21.         for (matchRay = 0; matchRay < rayCount; ++matchRay)
    22.         {
    23.             if(matchRay == 0)
    24.             {
    25.                 if(Physics.Raycast(new Vector3(centrePoint.transform.position.x + 8, 0, 0), centrePoint.transform.position, out hit, 10f, whatCanBeHit))
    26.                 {
    27.                     spawnPositions.Add(hit.point);
    28.                 }
    29.             }
    30.             else
    31.             {
    32.                 if(Physics.Raycast(new Vector3(centrePoint.transform.position.x - 8, 0, 0), centrePoint.transform.position, out hit, 10f, whatCanBeHit))
    33.                 {
    34.                     spawnPositions.Add(hit.point);
    35.                 }
    36.             }
    37.         }
    38.     }
    39.  
    40.     void Update()
    41.     {
    42.         if(matchRay == rayCount)
    43.         {
    44.             SpawnComponent();
    45.             ++matchRay;
    46.         }
    47.     }
    48.  
    49.     void SpawnComponent()
    50.     {
    51.         for(matchCount = 0; matchCount < numberOfComponents; ++matchCount) //run the loop until the max components has been reached
    52.         {
    53.             int randomNum = Random.Range(0, spawnPositions.Count);
    54.             Vector3 chosenPosition = spawnPositions[randomNum];
    55.  
    56.             Debug.Log(chosenPosition); //for testing
    57.  
    58.             GameObject environmentpiece = Instantiate(environmentPrefabs[Random.Range(0,environmentPrefabs.Count)]/*this works*/,
    59.             chosenPosition/*this does not*/, Random.rotation);
    60.         }
    61.     }
    62. }
    63.  
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,481
    The exception tells you the index or you could just attached the debugger to it and look at the values of everything i.e. debug it. All it means is that you're using an invalid index. Debugging will tell you what that is. That exception is used for anything that uses an index, it's not a list-thing. It'd do it with an array too.

    Even without that, what happens if you don't get any raycasts results? spawnPositions will be empty yet you'll still do "int randomNum = Random.Range(0, spawnPositions.Count);" which will return 0 and you'll go ahead and try to access that index which doesn't exist i.e. your list would be empty and bang, exception!

    You added a Debug.Log but that's after you get the exception i.e. after you try to access the position! Simply add a debug.log before it looking at what the spawnPositions.Count is.

    In short, you just need to debug it. :)
     
    PraetorBlue likes this.
  3. eeveahy-x

    eeveahy-x

    Joined:
    Mar 12, 2022
    Posts:
    14
    You're right, my raycasts are not producing any spawnPositions, so the issue I have now is fixing that. How can I tell the loop I already have to repeat itself if no raycast is produced? The fix that I tried made my unity crash (I made an infinite loop :eek:).

    Thanks for suggesting the debugger, also. I use VS code and it seems like I didn't have it installed.
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,481
    I cannot really tell you how to rewrite your code, I have no idea what you're doing or why or how you'd want to try again, how many times etc.

    I will say that your Raycasts look wrong. You're passing in two world-space positions. Take a look at the docs, it doesn't take that, it takes a position and a direction i.e. a ray.

    What you should be doing there is a Linecast i.e. a line-segment not a ray.
     
    PraetorBlue, eeveahy-x and mopthrow like this.
  5. eeveahy-x

    eeveahy-x

    Joined:
    Mar 12, 2022
    Posts:
    14
    Got it working now! Thanks! :D
     
    Kurt-Dekker and MelvMay like this.
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,727
    Excellent! For future reference:

    Here are some notes on IndexOutOfRangeException and ArgumentOutOfRangeException:

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

    Steps to success:
    - find which collection it is (critical first step!)
    - find out why it has fewer items than you expect
    - fix whatever logic is making the indexing value exceed the collection
    - remember you might have more than one instance of this script in your scene/prefab