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 /
  • Help Room /
avatar image
0
Question by LagSik · Aug 12, 2021 at 08:36 PM · colliderarraylistsforeachmissingreferenceexception

How to deal with a missing reference when an object referred each frame from an array is destroyed along the way?

Context:

In the Start method, I instantiate a flock of flying bugs and store them in a list called "agents".

In the Update method, I iterate on each agent in the list to: 1) store their transforms, 2) get a list of its neighbors' transforms and 3) calculate the movement of the flock based on the agent and its neighbors.

To check for neighbors, I used a method called GetNearbyObject to which I passed each agent. This method looks for colliders in a certain radius and store them in an array of colliders. Then, it iterate on each collider in the array to get their transforms. It returns a list of transforms that is needed to calculate the movement of the flock for each frame.

Problem:

My problem is that my flying bugs can be destroyed anytime when the player shoots at them. When a bug is killed, I get a "Missing Reference" error saying that one of my bug has been destroyed while the code still tries to access it.

It seems that since my bugs' colliders are stored in the array of colliders each frame, I can't manage to tell my code to ignore the newly destroyed bug's collider. I tried to add some if statements to check if a bug agent returns null and then remove it from both lists, but it doesn't remove the Missing Reference. I've also tried to disable the bugs' colliders when they return null after being destroyed. Doesn't work either.

If someone could help me get rid of this error, that would help me a lot in my learning curve of Unity and C#. Here is the concerned block of code:

 void Update()
 {
     foreach (FlockAgent agent in agents)
     {
         if (agent == null)
         {
             agents.Remove(agent);
         }
 
         List<Transform> context = GetNearbyObjects(agent);
         
         if (agent == null)
         {
             context.Remove(agent.transform);
         }
 
         Vector3 move = behavior.CalculateMove(agent, context, this);
 
         move *= driveFactor;
         if (move.sqrMagnitude > squareMaxSpeed)
         {
             move = move.normalized * maxSpeed;
         }
         agent.Move(move);
     }
 }
 
 List<Transform> GetNearbyObjects(FlockAgent agent)
 {
     
     List<Transform> context = new List<Transform>();
 
     Collider[] contextColliders = Physics.OverlapSphere(agent.transform.position, neighborRadius);
 
     foreach (Collider c in contextColliders)
     {
         if (c == null)
         {
             context.Remove(c.transform);
         }
         else if (c != agent.AgentCollider)
         {
             context.Add(c.transform);
         }
     }
     return context;
 }
Comment
Add comment · Show 1
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 rage_co · Aug 13, 2021 at 02:50 AM 0
Share

It is very simple with lists like you are using....you see in the script where you destroy the bug.....just before destroying....reference the script with the list in in.....and do this..

 referencedScript.bugList.Remove(bugToDestroy.GetComponent<Collider>());

obviously this is all kind of a pseudo code, you need to adjust the na$$anonymous$$g according to your script

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Will_Dev · Aug 14, 2021 at 06:15 AM

Need help with the same problem, gonna watch this thread

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
0

Answer by junk_rat_angel · Aug 14, 2021 at 07:30 AM

I think youve basically got this problem https://www.techiedelight.com/remove-elements-from-list-while-iterating-csharp/

Comment
Add comment · Show 7 · 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 LagSik · Aug 17, 2021 at 02:15 AM 0
Share

Indeed. But my problem is about removing an item from an array of colliders during iteration, while the article you kindly share is about removing item from a list. I've tried to adapt the solution to my problem with no luck.

I've tried to use a list of colliders instead by checking nearby colliders with OnTriggerEnter(). For some reason, it messes with the movement and physics of my flock (because of the isTrigger parameter I suppose). I've also tried to implement a for loop to check if an element returns null and then destroy/clear the array slot. No more luck.

I'm still looking for an answer. Thanks for your help though.

avatar image rage_co LagSik · Aug 17, 2021 at 04:23 AM 0
Share

you cannot simply delete the elements from an array....the solution is to implement something like this...let's assume originalArray is an array of strings...obviously you can implement this to any kind of array....you just need to replace the List.Remove part with this..

 string elementToDestroy = "y";
 int elementInstances = 0;
 
 foreach(string el in originalArray)
 {
   if(el == elementToDestroy)
   {
     elementInstances ++;
   }
 }
 
 string[] copyArray = new string[originalArray.Length - elementInstances];
 
 int currentElement = 0;
 for(int i=0; i < originalArray.Length; i++)
 {
   if(originalArray[i] != elementToDestroy)
   {
     copyArray[currentElement] = originalArray[i];
     currentElement++;
   }
 }
 originalArray = copyArray;

sure this is a bit bulky, but i guess it's something to be expected when working with arrays

avatar image LagSik rage_co · Aug 24, 2021 at 07:16 PM 0
Share

Hi rage_co. Thank for your insight. I've try to implement your suggestion and the thing is: I dont know in advance what will be the elementToDestroy (which are colliders) has it depends on which enemy or enemies the player will kill first. Therefore, I cannot declare the giving variable in advance nor run your solution. I've try to workaround this using a list of colliders to store every elementToDestroy. Here is my logic code:

      List<Collider> elementToDestroy = new List<Collider>;
      int elementInstances = 0;
      
      foreach(Collider item in originalArray)
      {
        if(el == null)
        {
 elementToDestroy.Add(item)
 elementInstances ++;
        }
      }
      
      Collider[] copyArray = new Collider[originalArray.Length - elementInstances];
      
      int currentElement = 0;
      for(int i=0; i < originalArray.Length; i++)
      {
        if(originalArray[i] != elementToDestroy[i])
        {
          copyArray[currentElement] = originalArray[i];
          currentElement++;
        }
      }
      originalArray = copyArray;

Unfotunatly, this code returns en error: "ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection". The error is link to the line 46 in the code block from the orignal post, where return context is called. I can't manage to get my head around this problem. Any suggestion would be much appreciated?

Show more comments

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

221 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

Related Questions

Compare GameObject with an array 1 Answer

Checking if a point is withing any of the colliders 1 Answer

Running foreach command on a int array 0 Answers

Using foreach to remove and delete bullet in List - C# 3 Answers

Creating card game - copy of list to new list - creating cycle 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