Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by intifernandez2004 · May 31, 2021 at 01:39 PM · 2dgameobjectlistspawnerout of range

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

Good day everyone. I'm new on unity. I'm trying to create a "light gun shooter" game. I have 17 positions where enemies may apear and a List to save each enemy instanciated by a prefab. The problem is that when I try to delete the GameObject of the list it seems to be out of the range. I've been trying and it looks like the GameObject is not correctly being added to the List. This is part of my code from the EnemySpawner:

 public class EnemySpawner : MonoBehaviour
  {
  
      public GameObject enemy;
      public GameObject enemySpawner;
  
      public Vector2[] position;
      List<GameObject> enemies = new List<GameObject>();
      static int enemiesCount = 0;
      bool existGO = false;
      int randomPos;
      float nextSpawn = 4f;
  
      void Update()
      {
          if (Time.time > nextSpawn)
          {
              if (nextSpawn <= 15)
              {
                  nextSpawn = Time.time + Random.Range(2f,3f);
              } else if (nextSpawn > 15 && nextSpawn <= 30)
              {
                  nextSpawn = Time.time + Random.Range(1.5f,2.5f);
              } else
              {
                  nextSpawn = Time.time + Random.Range(0.7f,1.7f);
              }
  
              randomPos = Random.Range(0,(position.Length - 1));
              for (int i = 0 ; i < enemiesCount ; i++)
              {
                  if (enemies[i].transform.position == new Vector3 (position[randomPos].x,position[randomPos].y,0))
                  {
                      existGO = true;
                  }
              }
              
              if (existGO == false)
              {
                  GameObject myEnemy = Instantiate(enemy);
                  myEnemy.transform.SetParent(enemySpawner.transform, false);
                  myEnemy.transform.position = new Vector3(position[randomPos].x, position[randomPos].y, 0);
                  enemies.Add(myEnemy);//This Seems Not To Be Working Well
                  enemiesCount += 1;
                  Debug.Log(enemiesCount); //Works fine
                  existGO = false;
              }            
          }
      }
      
      public void RemoveEnemy(GameObject enemigo)
      {
          Debug.Log(enemies[0].transform.position);//Out Of Range
          for (int i = 0 ; i < enemiesCount ; i++)
          {
              Debug.Log(enemies[i].transform.position);//Out Of Range
              if (enemies[i].transform.position == enemigo.transform.position)//Out Of Range
              {
                  enemiesCount -= 1;
                  enemies.RemoveAt(i);
                  Destroy(enemigo);
              }
          }
      }
  }


Thanks to everyone who can help me.

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image CodesCove · May 31, 2021 at 03:28 PM 0
Share

This will not solve the problem but maybe point you the correct way to debug the problem..

Why do you use private static enemiesCount? And should there only be one Spawner in the scene (it seems like there cloud be multiple) Basically what you do is that if you have multiple spawners then you can share this common counter, but it really will show the aggregate number of enemies in all of your enemy lists and there is no way to use it with individual enemy list. When you iterate the list you can use enemies.Count to get the list size. So in your Debug.Log(enemiesCount); use rather Debug.Log(enemies.Count); to get the actual list size.

avatar image logicandchaos · Jun 01, 2021 at 02:57 PM 0
Share

instead of using enemiesCount you should be using the built in enemies.Count, that will show how many elements are in your list, without you having to manually update it. Another solution seeing as it is static would be to increment and decrement it in OnStart() and OnDestroy() or OnEnable() OnDisable(), but the 1st solution makes this one unnecessary.

Using Debug.Log(enemies.Contains(myEnemy)); will let you know if it has been added to the list.

Try comparing enemiesCount to enemies.Count also Debug.Log(enemies[i].transform.position + "i value: "+ i); will show what iteration of the loop you are on when it fails.

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by Eno-Khaon · Jun 01, 2021 at 07:50 PM

When looping through a List<> with the intent to remove elements, you should start at the end and work your way to the front. This way, you don't unintentionally skip elements or loop beyond the end of the List when you actually remove the contents.

 for(int i = enemies.Count - 1; i >= 0; i--)
 {
     // Removing contents is safe
 }


The alternative would be along the lines of modifying the iterator (i) and final count (enemiesCount) to carefully ensure that you don't skip elements or bypass the end of the List. Starting at the end and going backwards is also computationally more efficient, however, since the starting point (enemiesCount - 1), iterator (i), and ending point (0) will never have to change during the loop.

Edit: Changed from "enemiesCount" to "enemies.Count" primarily because an instanced List with static quantity makes no sense.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by jackmw94 · Jun 01, 2021 at 05:36 PM

I think this is happening because you remove an enemy during your for-loop.

Say your enemies list contains enemies called A, B and C, your enemiesCount will equal 3. When you go to remove B you'll specify a loop that iterates 3 times: first run it'll pass by A, second run it'll find B and remove it causing your list to only have 2 elements in, third run you expect it to be comparing against C but at this point i == 2 and therefore will be out of range.

Luckily lists have a 'Remove' function that takes the object you're trying to remove. This function returns the index of the object it just removed, or -1 if it didn't remove an object. So - although this won't happen in your current setup - if it didn't remove an object you can detect this by checking if the index is < 0.

Although should be the fix to your problem, read both the comments as they're super useful to help you solve this yourself next time.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

319 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

2D GameObject Array to 2D List 1 Answer

A node in a childnode? 1 Answer

can't detect what player collides with, tried everything and all other posts... 2 Answers

(2d) How can I destroy a gameObject when I pass over it? 1 Answer

Create clickable GameObjects (JS) 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges