Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug beginner's mistake Help Me

Discussion in 'Scripting' started by aleksey140790, Jul 31, 2023.

  1. aleksey140790

    aleksey140790

    Joined:
    Jan 7, 2023
    Posts:
    9
    using System.Collections;
    using System.Collections.Generic;
    using System.Security.Cryptography.X509Certificates;
    using UnityEngine;
    using UnityEngine.UIElements;

    public class RoadGenerator : MonoBehaviour
    {
    public GameObject roadPrefabs;
    private List<GameObject> roads = new List<GameObject>();
    public float maxSpeed =10;
    private float speed = 0;
    private int maxRoadCount = 5;



    private void Start()
    {
    ResetLevel();
    StartLevel();
    CreateNextRoad();
    }

    private void Update()
    {
    if (speed == 0) return;
    foreach (GameObject road in roads)
    {
    road.transform.position -= new Vector3(0, 0, speed * Time.deltaTime);
    }

    if (roads[0].transform.position.z < -15)
    {
    Destroy(roads[0]);
    roads.RemoveAt(0);
    CreateNextRoad();
    }
    }

    public void CreateNextRoad()
    {

    Vector3 pos = Vector3.zero;
    if (roads.Count > 0)
    {
    GameObject go = Instantiate(roadPrefabs, pos, Quaternion.identity);
    go.transform.SetParent(transform);
    roads.Add(go);

    }

    }
    public void StartLevel()
    {
    speed = maxSpeed;
    }



    public void ResetLevel()
    {
    speed = 0;
    while (roads.Count > 0)
    {
    Destroy(roads[0]);
    roads.RemoveAt(0);
    }
    for (int i =0; i < maxRoadCount; i++)
    {
    CreateNextRoad();
    }


    }
    }


    Тhis code outputs ,this mistake

    ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index

    what to do???
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    Here's how to post code on the forums: https://forum.unity.com/threads/using-code-tags-properly.143875/

    Debug it and ensure you're not passing a negative value or a value less then the size of the collection as it tells you.
     
  3. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    It looks like your error probably happens here:
    Code (CSharp):
    1. foreach (GameObject road in roads)
    2. {
    3.    road.transform.position -= new Vector3(0, 0, speed * Time.deltaTime);
    4. }
    Because you run CreateNextRoad() 5 times in a loop, during your Start() void, to which it then checks:
    Code (CSharp):
    1. if (roads.Count > 0)
    Which would return false, those 5 iterations, since you never made at least one road yet. Then everything reads up until you call the "foreach" method, to which the list.Count is 0.

    In your "public void ResetLevel()", after clearing the list, you need to create at least one starter road, so the rest of your checks can work when checking if the count is greater than 0.

    I could be completely wrong, as it's hard to read without C# indentation.
     
  4. aleksey140790

    aleksey140790

    Joined:
    Jan 7, 2023
    Posts:
    9






    fixed start(), the wrong error again.
     
  5. aleksey140790

    aleksey140790

    Joined:
    Jan 7, 2023
    Posts:
    9
  6. aleksey140790

    aleksey140790

    Joined:
    Jan 7, 2023
    Posts:
    9
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Security.Cryptography.X509Certificates;
    4. using UnityEngine;
    5. using UnityEngine.UIElements;
    6.  
    7. public class RoadGenerator : MonoBehaviour
    8. {
    9.     public GameObject roadPrefabs;
    10.     private List<GameObject> roads = new List<GameObject>();
    11.     public float maxSpeed =10;
    12.     private float speed = 0;
    13.     private int maxRoadCount = 5;
    14.  
    15.  
    16.  
    17.     private void Start()
    18.     {
    19.         ResetLevel();
    20.         StartLevel();
    21.        
    22.     }
    23.  
    24.     private void Update()
    25.     {
    26.         if (speed == 0) return;
    27.         foreach (GameObject road in roads)
    28.         {
    29.             road.transform.position -= new Vector3(0, 0, speed * Time.deltaTime);
    30.         }
    31.      
    32.         if (roads[0].transform.position.z < (-15))
    33.         {
    34.             Destroy(roads[0]);
    35.             roads.RemoveAt(0);
    36.             CreateNextRoad();
    37.         }
    38.     }
    39.  
    40.     public void CreateNextRoad()
    41.     {
    42.  
    43.         Vector3 pos = Vector3.zero;
    44.         if (roads.Count > )
    45.         {
    46.             GameObject go = Instantiate(roadPrefabs, pos, Quaternion.identity);
    47.             go.transform.SetParent(transform);
    48.             roads.Add(go);
    49.  
    50.         }
    51.        
    52.     }
    53.     public void StartLevel()
    54.     {
    55.         speed = maxSpeed;
    56.     }
    57.  
    58.  
    59.  
    60.     public void ResetLevel()
    61.     {
    62.         speed = 0;
    63.         while (roads.Count > 0)
    64.         {
    65.             Destroy(roads[0]);
    66.             roads.RemoveAt(0);
    67.         }
    68.         for (int i =0; i < maxRoadCount; i++)
    69.         {
    70.             CreateNextRoad();
    71.         }
    72.  
    73.  
    74.     }
    75. }
    76.  
    Code (CSharp):
    1.  
    [ICODE]
    [/ICODE]
     
  7. aleksey140790

    aleksey140790

    Joined:
    Jan 7, 2023
    Posts:
    9
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class TileGenerator : MonoBehaviour
    6. {
    7.     public GameObject[] tilePrefabs;
    8.     private List<GameObject> activeTiles = new List<GameObject>();
    9.     private float spawnPos = 0;
    10.     private float tileLength = 100;
    11.  
    12.  
    13.     [SerializeField] private Transform player;
    14.     private int startTiles = 6;
    15.  
    16.     // Start is called before the first frame update
    17.     void Start()
    18.     {
    19.         for (int i = 0; i < startTiles; i++)
    20.         {
    21.             SpawnTile(Random.Range(0,tilePrefabs.Length));
    22.         }
    23.     }
    24.  
    25.     // Update is called once per frame
    26.     void Update()
    27.     {
    28.         if (player.position.z - 60> spawnPos - (startTiles * tileLength))
    29.         {
    30.             SpawnTile(Random.Range(0, tilePrefabs.Length));
    31.             DeleteTile();
    32.         }                            
    33.     }
    34.  
    35.     private void SpawnTile(int tileIndex)
    36.     {
    37.         GameObject nextTile = Instantiate(tilePrefabs[tileIndex], transform.forward * spawnPos, transform.rotation);
    38.         activeTiles.Add(nextTile);
    39.         spawnPos += tileLength;
    40.     }
    41.     private void DeleteTile()
    42.     {
    43.         Destroy(activeTiles[0]);
    44.         activeTiles.RemoveAt(0);
    45.     }
    46. }



    Same mistake on this code
     
  8. aleksey140790

    aleksey140790

    Joined:
    Jan 7, 2023
    Posts:
    9
    here
     

    Attached Files:

  9. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    You're obviously more of a hands-on person, so I fixed it to what I think you want:
    Code (CSharp):
    1. public class RoadGenerator : MonoBehaviour
    2. {
    3.     public GameObject roadPrefabs;
    4.     private List<GameObject> roads = new List<GameObject>();
    5.     public float maxSpeed =10;
    6.     private float speed = 0;
    7.     private int maxRoadCount = 5;
    8.  
    9.  
    10.     private void Start()
    11.     {
    12.         ResetLevel();
    13.         StartLevel();
    14.         //CreateNextRoad(); // 5 roads already made from ResetLevel()
    15.     }
    16.  
    17.     private void Update()
    18.     {
    19.         if (speed == 0) return;
    20.         foreach (GameObject road in roads)
    21.         {
    22.             road.transform.position -= new Vector3(0, 0, speed * Time.deltaTime);
    23.         }
    24.  
    25.         if (roads[0].transform.position.z < -15)
    26.         {
    27.             Destroy(roads[0]);
    28.             roads.RemoveAt(0);
    29.             CreateNextRoad();
    30.         }
    31.     }
    32.  
    33.     public void CreateNextRoad()
    34.     {
    35.         // if all this function does is just create another road
    36.         // it can be simplified, if at Vector(0,0,0) and if
    37.         // parent is this transform:
    38.         GameObject go = Instantiate(
    39.             roadPrefabs, // object to make
    40.             Vector3.zero, // static call for (0,0,0)
    41.             Quaternion.identity, // base rotation
    42.             transform); // parent to set
    43.         roads.Add(go); // add to the list
    44.     }
    45.  
    46.     public void StartLevel()
    47.     {
    48.         speed = maxSpeed;
    49.     }
    50.  
    51.     public void ResetLevel()
    52.     {
    53.         speed = 0;
    54.         while (roads.Count > 0)
    55.         {
    56.             Destroy(roads[0]);
    57.             roads.RemoveAt(0);
    58.         }
    59.         for (int i =0; i < maxRoadCount; i++)
    60.         {
    61.             CreateNextRoad();
    62.         }
    63.     }
    64. }
    But I notice this will make 5 roads all at 0, and slowly move them back, so you would need to set the positions so that they are more in a chained formation. But that should be a simple fix
     
    Last edited: Jul 31, 2023
  10. aleksey140790

    aleksey140790

    Joined:
    Jan 7, 2023
    Posts:
    9
    But I notice this will make 5 roads all at 0, and slowly move them back, so you would need to set the positions so that they are more in a chained formation. But that should be a simple fix[/QUOTE]


    Thank you you fixed !!! You're right now 5 roads are being created in one place 0,0,0.
     
  11. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    You're welcome, so you'd have to change:
    Code (CSharp):
    1. public void CreateNextRoad(Vector3 pos)
    2.     {
    3.         GameObject go = Instantiate(
    4.             roadPrefabs, // object to make
    5.             pos, // position to spawn at
    6.             Quaternion.identity, // base rotation
    7.             transform); // parent to set
    8.         roads.Add(go); // add to the list
    9.     }
    And in ResetLevel():
    Code (CSharp):
    1. for (int i =0; i < maxRoadCount; i++)
    2.         {
    3.             Vector3 position = new Vector3(0, 0, i * roadLength);
    4.             CreateNextRoad(position);
    5.         }
    You'll have to play with distances to see what the length is of the road piece. And if going backwards just set "i * roadLength" to a negative value by putting a minus symbol in front of it, after encapsulating:
    Code (CSharp):
    1. Vector3 position = new Vector3(0, 0, -(i * roadLength));
    And then change your constant Update call:
    Code (CSharp):
    1. if (roads[0].transform.position.z < -15)
    2.         {
    3.             Destroy(roads[0]);
    4.             roads.RemoveAt(0);
    5.             CreateNextRoad(Vector3.zero);
    6.         }
    And then you should be all set to explore further into the world of coding! Cheers!
     
    Last edited: Jul 31, 2023
  12. aleksey140790

    aleksey140790

    Joined:
    Jan 7, 2023
    Posts:
    9
    Thanks, but when I changed the code, the error that was the first one returned)))
    Maybe it's the editor, no matter how he rewrites the code for normal road generation, the same error occurs at once.
    I will delete the project and try to write again. ))
     
  13. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    So debugging your code doesn't help?

    Do you understand that if something such as a list is empty, you cannot just access any of its elements such as you're doing when you do "roads[0].xxx" on Line 32 above? This is what debugging is all about. Attach a debugger, step through it. You'll soon see that you get there in the update and there are no roads and you ask for road[0]. This is basic stuff and nothing specific to Unity. I would urge you to follow a C# tutorial and/or look at some docs on it and look at how to use lists and various other collections; it'll save you a lot of pain.

    A new project and typing it again would suggest that, with all due respect, you think it's somehow a broken
     
    Kurt-Dekker likes this.
  14. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    One way it would be the Editors fault, is when using public variables. As if something was set in the Editor, say "speed = 20" but the script says in Start() that "speed = 5", then it will always be 20, since that's what the Editor was set to(which helps sometimes, but hurts others).

    Your original problem was you were trying to access a list that had no objects in it, so it returned the error index was out of bounds. So how that would have come back, from any of the changes I mentioned, I'm not sure, that's weird.

    But you shouldn't have to scrap a whole project and start fresh, unless you changed a whole mess of project settings, and can't revert them back to normal(default).

    As was mentioned, debugging is your best friend. So play around with the print() function, and place it in key areas you may be having trouble:
    Code (CSharp):
    1. print($"roads in game {roadList.Count}, road 0 is at position {roadList[0].transform.position}");
    Putting the "$" in front of a string, makes it interpolated, meaning you can add in any game variables to a string easily with "{ }" brackets. And will help you to better understand how code works.
     
  15. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    Code (CSharp):
    1. // Check if there are any roads.
    2. if (roads.Count > 0)
    3. {
    4.     // I know there's at least a single road so I can touch road[0]...
    5.     if (roads[0].transform.position.z < -15)
    6.     {
    7.         Destroy(roads[0]);
    8.         roads.RemoveAt(0);
    9.         CreateNextRoad();
    10.     }
    11. }
     
  16. aleksey140790

    aleksey140790

    Joined:
    Jan 7, 2023
    Posts:
    9
    Thanks everyone, i fixed it !!!) Simple being writing scripts again))
     
    MelvMay and wideeyenow_unity like this.