- Home /
Remove a destroy object from a list, then reload the list
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class pRocketMod : MonoBehaviour {
//private Vector3 closestTarget;
private GameObject leftClosestTarget;
private GameObject rightClosestTarget;
//public GameObject rocket;
public GameObject leftRocket;
public GameObject rightRocket;
private float speed = 5.0f;
private float lifeTime;
public UniversalStats uStats;
public List<Collider> rCol = new List<Collider>();
void OnTriggerEnter(Collider other)
{
if (other.collider.tag == "Enemy") {
rCol.Add(other.gameObject.collider);
}
}
void RightRocketCheckDistance()
{
rightRocket.transform.position += Vector3.up * speed * Time.deltaTime;
if(rCol.Count > 0 && rightRocket != null)
{
foreach(Collider r in rCol)
{
rightRocket.transform.LookAt(r.transform.position);
rightRocket.transform.position = Vector3.MoveTowards(rightRocket.transform.position, r.transform.position,15.0f * Time.deltaTime);
if(Vector3.Distance(r.transform.position,rightRocket.transform.position) < 2.5f && r.gameObject.tag == "Enemy")
{
Destroy(r.gameObject);
rCol.Remove(r.collider);
Destroy(rightRocket);
}
}
}
}
void Update()
{
RightRocketCheckDistance ();
}
}
InvalidOperationException: Collection was modified; enumeration operation may not execute. System.Collections.Generic.List`1+Enumerator[UnityEngine.Collider].VerifyState () (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:778) System.Collections.Generic.List`1+Enumerator[UnityEngine.Collider].MoveNext () (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:784) pRocketMod.RightRocketCheckDistance () (at Assets/PlayerFolder/PlayerScripts/pRocketMod.cs:36) pRocketMod.Update () (at Assets/PlayerFolder/PlayerScripts/pRocketMod.cs:53)
MissingReferenceException: The object of type 'BoxCollider' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object. UnityEngine.Component.get_transform () (at C:/BuildAgent/work/d63dfc6385190b60/artifacts/EditorGenerated/UnityEngineComponent.cs:20) pRocketMod.RightRocketCheckDistance () (at Assets/PlayerFolder/PlayerScripts/pRocketMod.cs:38) pRocketMod.Update () (at Assets/PlayerFolder/PlayerScripts/pRocketMod.cs:53)
Those are the two errors Im getting. I've been trying to find ways around them, but it somehow causes more errors.
So does anyone have a solution to this?
I added an answer with example code with the same idea that meat5000 had (I posted before I saw his comment)
Answer by Cherno · Mar 03, 2015 at 03:04 AM
If you want to iterate through a collection and modify it while doing so (such as removing or adding items), don't use a foreach loop. Use a normal for... loop, but do it in reverse like this, and you will get no errors. Otherwise, the current index gets messed up.
for (int i = rCol.Count - 1; i >= 0; i--) {
Collider r = rCol[i];
//Do whatever you want with r... Remove it from rCol, Destroy it,... it will work flawlessly.
}
Edit: I just saw that meat5000 already suggested this :)
void RightRocketCheckDistance()
{
for (int i = rCol.Count - 1; i >= 0; i--) {
Collider r = rCol[i];
rightRocket.transform.position += Vector3.up * speed * Time.deltaTime;
if(rCol.Count > 0 && rightRocket != null)
{
rightRocket.transform.LookAt(r.transform.position);
rightRocket.transform.position = Vector3.$$anonymous$$oveTowards(rightRocket.transform.position, r.transform.position,15.0f * Time.deltaTime);
if(Vector3.Distance(r.transform.position,rightRocket.transform.position) < 2.5f && r.gameObject.tag == "Enemy")
{
Destroy(r.gameObject);
rCol.Remove(r.collider);
Destroy(rightRocket);
}
}
}
}
I changed it to that and still get the missing reference errors.
if(rCol.Count > 0 && rightRocket != null)
Changed to
if(rCol.Count > 0 && rightRocket != null && r != null)
Fix'd the last bit of issues.
Thanks for the help!
Answer by TehJustice · Mar 03, 2015 at 02:06 AM
Haven't dissected the code yet to see if this is the issue, but you should never remove an object in the middle of the foreach loop.
It was doing it before that too. I'd prefer not to use the Foreach loop at all.
Seems like you might not need to. Why not check the distance from the trigger every time you get a collision?
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
how do I remove a class item from a list? 1 Answer
using Contains(gameObject) to find and destroy a gameObject from a list 2 Answers
Remove all duplicates from a list 1 Answer
Remove and resize List 1 Answer